Shell GNU find“or”函数不能与-print0 | xargs-0 tar一起使用
我使用这个命令来查找特定的文件2个文件,这些文件本身就可以正常工作Shell GNU find“or”函数不能与-print0 | xargs-0 tar一起使用,shell,unix,gnu-findutils,Shell,Unix,Gnu Findutils,我使用这个命令来查找特定的文件2个文件,这些文件本身就可以正常工作 find . -iname '*.txt' -o -iname '*.pdf' 并返回正确的文件 ./.folder1/file1.txt ./.folder1/file1.pdf ./.folder2/file2.txt ./.folder2/file2.pdf 但是,如果我试图将这些已建立的文件制作成tarball,它只包括find命令中的第一个iname部分,如下所示 find . -iname '*.txt' -o
find . -iname '*.txt' -o -iname '*.pdf'
并返回正确的文件
./.folder1/file1.txt
./.folder1/file1.pdf
./.folder2/file2.txt
./.folder2/file2.pdf
但是,如果我试图将这些已建立的文件制作成tarball,它只包括find命令中的第一个iname部分,如下所示
find . -iname '*.txt' -o -iname '*.pdf' -print0 | xargs -0 tar -czvf files.tar.gz
因此,在本例中不包括*.pdfs,而在tarball中只包括*.txts:
./.folder1/file1.txt
./.folder2/file2.txt
如何修复此问题,使*.txts和*.pdfs都成为一个tarball?首先,使用find…|xargs tar-c不是很好的建议:当find生成一个文件列表,文件太长以至于xargs拆分为多个tar调用时,除了最后一个调用之外,其他所有调用都将被覆盖
只运行一个tar副本并将其配置为从stdin读取更安全:
find . '(' -iname '*.txt' -o -iname '*.pdf' ')' -print0 |
tar -c --null -T - -zf backups.tar.gz
编写与find逻辑等效的shell时,原始/错误版本可能如下所示:
for f in *; do
{ [[ $f = *.txt ]]; } || \
{ [[ $f = *.pdf ]] && printf '%s\0' "$f"; }
done
如果*.txt分支为true,则实际上不会执行任何操作,因为printf仅以*.pdf为条件
使用paren对分支进行分组:
find . '(' -iname '*.txt' -o -iname '*.pdf' ')' -print0
…这使得逻辑看起来像:
for f in *; do
{ [[ $f = *.txt ]] || [[ $f = *.pdf ]]; } && printf '%s\0' "$f";
done
或者在每一侧放置一份单独的操作副本:
find . -iname '*.txt' -print0 -o -iname '*.pdf' -print0
…其行为类似于:
for f in *; do
{ [[ $f = *.txt ]] && printf '%s\0' "$f"; } || \
{ [[ $f = *.pdf ]] && printf '%s\0' "$f"; }
done
首先,使用find…|xargs tar-c不是很好的建议:当find生成一个文件列表,文件太长以至于xargs拆分为多个tar调用时,除了最后一个调用之外,其他所有调用都将被覆盖
只运行一个tar副本并将其配置为从stdin读取更安全:
find . '(' -iname '*.txt' -o -iname '*.pdf' ')' -print0 |
tar -c --null -T - -zf backups.tar.gz
编写与find逻辑等效的shell时,原始/错误版本可能如下所示:
for f in *; do
{ [[ $f = *.txt ]]; } || \
{ [[ $f = *.pdf ]] && printf '%s\0' "$f"; }
done
如果*.txt分支为true,则实际上不会执行任何操作,因为printf仅以*.pdf为条件
使用paren对分支进行分组:
find . '(' -iname '*.txt' -o -iname '*.pdf' ')' -print0
…这使得逻辑看起来像:
for f in *; do
{ [[ $f = *.txt ]] || [[ $f = *.pdf ]]; } && printf '%s\0' "$f";
done
或者在每一侧放置一份单独的操作副本:
find . -iname '*.txt' -print0 -o -iname '*.pdf' -print0
…其行为类似于:
for f in *; do
{ [[ $f = *.txt ]] && printf '%s\0' "$f"; } || \
{ [[ $f = *.pdf ]] && printf '%s\0' "$f"; }
done
-o的优先级低于连接-iname'*.pdf'和-print0的隐式-a。您需要将参数插入到-o中:
“查找”仅在没有指定任何操作的情况下添加隐式打印。如果没有括号,您将有一个显式-print0,这将阻止隐式-print应用于第一个-iname主的结果。-o的优先级低于连接-iname'*.pdf'和-print0的隐式-a。您需要将参数插入到-o中:
“查找”仅在没有指定任何操作的情况下添加隐式打印。如果没有括号,您就有一个显式-print0,它可以防止隐式-print应用于第一个-iname主进程的结果。很抱歉,我忘了回答,这一个非常有用!非常感谢!对不起,我忘了回复,这封信很有魅力!非常感谢!