2014-09-27 52 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