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

时间:2016-01-29 13:25:58

标签: bash shell scripting rsync placeholder

我遇到这种情况,其中包含文件和链接(!)的模板目录需要递归复制到目标目录,同时保留所有属性。模板目录包含任意数量的占位符(__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__替换为“值”,可能使用cpfindrsync

2 个答案:

答案 0 :(得分:2)

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

find ./template -type f

find ./template ! -type d

否则,显而易见的解决方案是使用cp -a制作&#34;存档&#34;模板的副本,包含所有链接,权限等,然后重命名副本中的占位符。

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,否则重命名目录中的文件将会中断。

如果对您来说非常重要的是创建目录树并且名称已经更改(即您必须永远不会在目的地中看到占位符),那么我建议您只使用中间位置。< / p>

答案 1 :(得分:0)

使用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="$1"
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 {} \;