2012-12-25 38 views
4

我必須做一個腳本,它將主目錄中的所有* .txt文件複製到此第一個參數中指定的新創建的目錄腳本($ {1})。

如果備份目錄已經存在,我想跳過它。我正在嘗試-prune排除查找,但它不適用於我。最後,我已經在循環中做了if語句,這也是行不通的,我不知道爲什麼......感謝您的幫助!

這裏是我的代碼:

#!/bin/bash 

mkdir ${1} 

for file in $(find ~/ -name *.txt) 

do 

    if [ ! -f ~/${1}/$file ] 
    then 
     cp -i -v $file -t ~/${1} 
    fi 

done 
+0

」不適合我「......呃,好吧。怎麼樣? –

+0

如果你不需要目錄遞歸,'cp * .txt destination /',可能用'cp -n'。另見'rsync'。 – tripleee

回答

0

你在代碼中有一個錯誤,你所創建的目錄:

mkdir ${1} 

但複製和測試不同的路徑(-f ~/${1}/$file-t ~/${1})。創建一個變量來避免這樣的錯誤:

#!/bin/bash 
dest=~/${1} 
[ -d "$dest" ] || mkdir "$dest" 
SAVEIFS=$IFS 
IFS=$(echo -en "\n\b") 
for file in $(find ~/ -name '*.txt' -print) 
do 
    dfile="$dest/"$(basename "$file") 
    if [ "$file" -ef "$dfile" ]; then 
    echo same 
    else 
    cp -i -v "$file" -t "$dfile" 
    fi 
done 
IFS=$SAVEIFS 
+0

文件在其名稱中有空格時立即中斷。而且,絕對/相對路徑有點笨拙。 –

+0

感謝您的回覆,但cp仍在嘗試將文件從$ dest路徑複製到$ dest路徑... – jirinovo

+0

http://mywiki.wooledge.org/DRLWF – ormaaj

0

您可以簡化這

mkdir -p "$1" 
find ~/ -name "$1" -prune , -name '*.txt' -print0 | xargs -0 cp -n -v -t "$1" 

您必須引用*.txt,否則shell將其擴大到所有.txt文件在當前目錄不是搜索的所有.txt文件在您的主目錄下。 -name "$1" -prune不包括備份目錄。

xargs調用cp儘可能多的文件名,因此節省了大量的時間。

cp -n而不是cp -i可防止覆蓋已存在的文件。如果你想保留它,當然你可以用-i代替-n

如果要保留目錄層次結構,rsync可能更適合此備份任務。

1

這應該這樣做:

#!/bin/bash 

[[ -n "$1" ]] || { echo >&2 'Give me an argument!'; exit 1; } 

destdir=$(readlink -m -- "$1") 

[[ "$destdir" == *\** ]] && { echo >&2 "Sorry, I'm in the stupid situation where the destination dir contains the \`*' character. I can't handle this."; exit 1; } 

mkdir -pv -- "$destdir" || { echo >&2 "Couldn't create directory \`$destdir'. Sorry."; exit 1; } 

find "$HOME" -path "$destdir" -prune -o \(-name '*.txt' -exec cp -iv -t "$destdir" -- {} \; \) 

臨:與有空格或有趣的符號,他們的名字(不像你)文件作品(除了一個愚蠢的情況,請參見下面精讀)。如果你的目標路徑名包含模式字符*,這可能會失敗。這種情況已被安全地考慮在內,如果腳本發生,腳本會優雅地退出。

解釋。

  • 給出該腳本的參數。它可以是相對於當前目錄的絕對值。 readlink-m選項將小心將其轉換爲絕對路徑:這是變量destdir
  • 目錄$destdir由其父母(如果適用)創建。
  • 在主目錄中,如果我們找到$destdir目錄,我們修剪這個分支,否則,我們查找所有*.txt文件並將它們複製到$destdir

再次,這個腳本是100%安全的關於與搞笑符號的文件名:空格,換行字符或連字符,除了在目標目錄名模式字符*,但這種情況下,通過優美的安全處理退出,而不是潛在的搞砸文件。 「

+0

當destdir包含模式字符時它不安全。通常,'-path'和'-prune'不會混合。與globs不同,'-path'不會分別評估每個路徑組件。例如'/ foo/*/bork'匹配'/ foo/bar/bork'和'/ foo/bar/baz/bork'。 – ormaaj

+0

@ormaaj你說得對!我忘了愚蠢的模式字符'*'。現在你爲什麼說'-path'和'-prune'不混合?在「man find」中一起使用它們有一個很好的例子。 –

+0

bleh right,我誤讀爲「use -name,而不是-path」。儘管這很接近。 – ormaaj

相關問題