2014-09-27 32 views
0

我需要創建一個目錄樹的克隆,以便我可以清理重複的文件。是否有創建硬鏈接備份的實用工具?

我不需要文件的副本,我只需要這些文件,所以我想創建一個與硬鏈接匹配的樹。

我在一兩分鐘一起扔這的時候,我意識到我的備份是要花費幾個小時

它只是回聲,我重定向到一個文件來檢查之前,我運行的命令。

過程中的常見問題,如文件和包含引號或逗號目錄還沒有得到解決中(bash的腳本很爛這一點,對不對,這和含引導破折號文件)

是不是有一些已經以強大的方式做到這一點的實用程序?

BASEDIR=$1 
DESTDIR=$2 
for DIR in `find "$BASEDIR" -type d` 
do 
    RELPATH=`echo $DIR | sed "s,$BASEDIR,,"` 
    DESTPATH=${DESTDIR}/$RELPATH 
    echo mkdir -p \"$DESTPATH\" 
done 

for FILE in `find "$BASEDIR" -type f` 
do 
    RELPATH=`echo $FILE | sed "s,$BASEDIR,,"` 
    DESTPATH=${DESTDIR}/$RELPATH 
    echo ln \"$FILE\" \"$DESTPATH\" 
done 

回答

1

一般使用發現一樣,是一個壞主意 - 你基本上是依靠對空格分隔的文件名的時候,其實一切形式的空白是因爲大多數UNIX系統上的文件名有效。查找本身能夠在找到的每個文件上運行單個命令,這通常是更好的使用方法。我建議做這樣的事情(我用幾個腳本此爲簡單起見,不知道這將是多麼容易做到這一切在一個):

main.sh:

BASEDIR="$1" #I tend to quote all variables - good habit to avoid problems with spaces, etc. 
DESTDIR="$2" 
find "$BASEDIR" -type d -exec ./handle_file.sh \{\} "$BASEDIR" "$DESTDIR" \; # \{\} is replaced with the filename, \; tells find the command is over 
find "$BASEDIR" -type f -exec ./handle_file.sh \{\} "$BASEDIR" "$DESTDIR" \; 

handle_file.sh:

FILENAME="$1" 
BASEDIR="$2" 
DESTDIR="$3" 
RELPATH="${FILENAME#"$BASEDIR"}" # bash string substitution double quoting, to stop BASEDIR being interpreted as a pattern 
DESTPATH="${DESTDIR}/$RELPATH" 
if [ -f "$FILENAME" ]; then 
    echo ln \""$FILENAME"\" \""$DESTPATH"\" 
elif [ -d "$FILENAME" ]; then 
    echo mkdir -p \""$DESTPATH"\" 
fi 

我用一個簡單的樹用空格,星號,省略號,甚至在文件名回車測試這一點,它似乎工作。

顯然刪除轉義引號和「回聲」(但留下真實的引號),使其真正的工作。

+0

好的解決方案,但對於支持它的'find','print0' .... | xargs -0 myMvCmd ...'可以處理任何文件名。祝你們好運。 – shellter 2014-09-27 22:24:05