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