2012-12-25 40 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

相关问题