如何复制包含占位符的目录结构

How do I copy directory structure containing placeholders

我有这样的情况,其中包含文件和链接 (!) 的模板目录需要递归复制到目标目录,同时保留所有属性。模板目录包含任意数量的占位符 (__NOTATION__),需要将其重命名为特定值。

例如模板如下所示:

./template/__PLACEHOLDER__/name/__PLACEHOLDER__/prog/prefix___FILENAME___blah.txt

目的地变成这样:

./destination/project1/name/project1/prog/prefix_customer_blah.txt

到目前为止我试过的是:

# first create dest directory structure
while read line; do
  dest="$(echo "$line" | sed -e 's#__PLACEHOLDER__#project1#g' -e 's#__FILENAME__#customer#g' -e 's#template#destination#')"
  if ! [ -d "$dest" ]; then
    mkdir -p "$dest"
  fi
done < <(find ./template -type d)

# now copy files
while read line; do
  dest="$(echo "$line" | sed -e 's#__PLACEHOLDER__#project1#g' -e 's#__FILENAME__#customer#g' -e 's#template#destination#')"
  cp -a "$line" "$dest"
done < <(find ./template -type f)

但是,我意识到,如果我要处理权限和链接,这将是无穷无尽的,而且非常复杂。有没有更好的方法将 __PLACEHOLDER__ 替换为 "value",也许使用 cpfindrsync

首先用rsync复制,保留所有属性和链接等。 然后更改目标文件名中的占位符字符串:

#!/bin/bash

TEMPL="$PWD/template" # somewhere else

DEST="$PWD/dest"      # wherever it is

mkdir "$DEST"
(cd "$TEMPL"; rsync -Hra . "$DEST")   # 
MyRen=$(mktemp)
trap "rm -f $MyRen" 0 1 2 3 13 15

cat >$MyRen <<'EOF'
#!/bin/bash
fn=""
newfn="$(echo "$fn" |  sed -e 's#__PLACEHOLDER__#project1#g' -e s#__FILENAME__#customer#g' -e 's#template#destination#')"
test "$fn" != "$newfn" &&  mv "$fn" "$newfn"
EOF

chmod +x $MyRen

find "$DEST" -depth -execdir $MyRen {} \;

我怀疑你的脚本已经可以做你想做的事了,只要你替换

find ./template -type f

find ./template ! -type d

否则,显而易见的解决方案是使用 cp -a 制作模板的 "archive" 副本,完成所有链接、权限等,然后 然后 重命名副本中的占位符。

cp -a ./template ./destination
while read path; do
  dir=`dirname "$path"`
  file=`basename "$path"`
  mv -v "$path" "$dir/${file//__PLACEHOLDER__/project1}"
done < <(`find ./destination -depth -name '*__PLACEHOLDER__*'`)

请注意,您需要使用 -depth,否则在重命名目录中重命名文件会失败。

如果创建目录树时名称已经更改(即您绝不能在目标位置看到占位符)对您来说非常重要,那么我建议您只使用一个中间位置。