2016-01-29 74 views
1

我有這種情況,需要將包含模板目錄的文件和鏈接(!) - 以遞歸方式複製到目標目錄,並保留所有屬性。模板目錄包含任意數量的佔位符(__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,findrsync

回答

2

我懷疑你的腳本就已經做你想做的,如果只有你更換

find ./template -type f 

find ./template ! -type d 

否則,明顯的解決方案是使用cp -a使模板的「歸檔」副本,完成所有環節,權限等,並然後重命名副本中的佔位符。

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否則重命名文件將打破。

如果目錄樹是使用已經更改的名稱創建的(即,您絕不會在目標中看到佔位符),那麼我建議您只使用中間位置。

+0

我也想過這個解決方案,這對我來說實際上是可行的。但我注意到,我將不得不從「從左到右」移動目錄。因爲例如mv ./template/__PLACEHOLDER__/name/__PLACEHOLDER__/prog/prefix___FILENAME___blah.txt ./destination/project1/name/project1/prog/prefix_customer_blah.txt導致「沒有這樣的文件或目錄」錯誤。 – g000ze

+0

這就是'-depth'的意義所在。 – ams

+0

的確如此。謝謝!將嘗試並回來。 – g000ze

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 {} \;