将唯一文件复制到新位置

时间:2013-11-16 12:41:37

标签: bash

我是Linux和bash脚本的新手,目前我很难解决这个问题!

我有一个包含许多图像的目录,我需要将这些图像复制到新位置。我知道有很多选择如何去做,但目前知识非常有限,所以欣赏我可能会以错误的方式解决这个问题。

我使用find和cat来创建此列表,并试图复制文件,以便在它们存在时比较它们(使用md5和检查文件名)。

但是,文本文件上有30个文件,但只复制了18个文件。有人可以建议吗?

我找到文件的代码是 -

find $1 -name "IMG_****.JPG" | cat > list.txt

我要从列表中复制的代码是

for image in $(cat list.txt);
do
cp $image $2
done

1 个答案:

答案 0 :(得分:5)

你做得太复杂了。不要将find输出传递给cat以将其传输到列表中。这是对cat的不必要使用。如果必须,您可以直接重定向每个程序的输出:

find "$1" -name "IMG_*.JPG" > list.txt

此外,do not use for to read lines from a file。更好use while with read

while read -r filename; do
    cp "$filename" "$2"
done < list.txt

但它更容易。您可以直接从find处理文件:

find "$1" -name "IMG_*.JPG" -exec cp {} "$2" \;

此处,{}将被find找到的每个文件名替换。不要忘记quote your variables,以便文件路径中的空格没有问题。

使用Bash选项的另一种更简单的方法:

shopt -s nullglob globstar
cp -t "$2" -- "$1"/**/IMG_*.JPG

此处,globstar通过**启用目录的递归匹配。 -t cp选项指定复制操作的目标。*命令将扩展为cp -t target -- source1/IMG_foo.JPG source2/IMG_bar.JPG等。


现在,关于您的原始问题,可能是某些图片的名称中有空格。这会打破原来的脚本。如果您的图片文件在其名称中包含换行符,那么它也不会与while read …一起使用 - 但在没有找到文件的情况下您会收到错误。

另请注意,cp会覆盖具有相同名称的文件。没有要求确认。因此,如果在您的子目录中有相同文件名的图像,您只能得到一个结果,最新的覆盖现有结果。

* --并非绝对必要,但是当选项参数结束时包含它以告诉命令是一个好习惯。