find . -name "filename including space" -print0 | xargs -0 ls -aldF > log.txt
find . -name "filename including space" -print0 | xargs -0 rm -rdf
是否可以将这两个命令合并为一个,以便只完成 1 个查找而不是 2 个?
我知道 xargs -I 可能有办法做到这一点,这可能会在处理包含空格的文件名时导致错误。非常感谢任何指导。
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt; rm -rdf {}'
刚刚碰到这个,我们可以减少调用 shell 的频率:
find . -name "filename including space" -print0 |
xargs -0 sh -c '
for file; do
ls -aldF "$file" >> log.txt
rm -rdf "$file"
done
' sh
尾随的“sh”在 shell 中变为 $0。xargs
将文件(从 中返回find
)作为命令行参数提供给 shell:我们使用 for 循环遍历它们。
如果您只是想避免find
多次执行,您可以在tee
之后立即执行find
,将find
输出保存到文件中,然后执行以下行:
find . -name "filename including space" -print0 | tee my_teed_file | xargs -0 ls -aldF > log.txt
cat my_teed_file | xargs -0 rm -rdf
完成同样事情的另一种方法(如果确实是您想要完成的)是将输出存储find
在变量中(假设它不是 TB 数据):
founddata=`find . -name "filename including space" -print0`
echo "$founddata" | xargs -0 ls -aldF > log.txt
echo "$founddata" | xargs -0 rm -rdf
我相信现在所有这些答案都给出了解决这个问题的正确方法。我尝试了 Jonathan 的 2 种解决方案和 Glenn 的方式,所有这些都在我的 Mac OS X 上运行良好。 mouviciel 的方法在我的操作系统上不起作用可能是由于某些配置原因。而且我认为它类似于乔纳森的第二种方法(我可能错了)。
正如对 Glenn 方法的评论中提到的,需要进行一些调整。所以这是我尝试过的命令,它非常适合仅供参考:
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} | tee -a log.txt ; rm -rdf {}'
或者按照 Glenn 的建议更好:
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt ; rm -rdf {}'
只要文件名中没有换行符,GNU Parallel 就不需要 -print0:
find . -name "My brother's 12\" records" | parallel ls {}\; rm -rdf {} >log.txt
观看介绍视频以了解更多信息:http ://www.youtube.com/watch?v=OpaiGYxkSuQ
只是xargs
方法的一种变体,没有那种可怕的-print0
and xargs -0
,这就是我的做法:
ls -1 *.txt | xargs --delimiter "\n" --max-args 1 --replace={} sh -c 'cat {}; echo "\n"'
脚注:
xargs
但为了读者的理解,我使用了较长的选项。ls -1
当我想要非递归行为而不是find -maxdepth 1 -iname "*.txt"
更冗长时,我会使用它。find
您可以在使用之后执行多个命令for
而不是xargs
:
IFS=$'\n'
for F in `find . -name "filename including space"`
do
ls -aldF $F > log.txt
rm -rdf $F
done
定义内部IFS
字段分隔符,默认为 <space><tab><newline>。如果您的文件名可能包含空格,则最好像上面那样重新定义它。
我迟到了,但这里没有介绍另一种解决方案:用户定义的函数。将多条指令放在一行上很笨拙,并且很难阅读/维护。上面的 for 循环避免了这种情况,但有可能超过命令行长度。
这是另一种方式(未经测试)。
function processFiles {
ls -aldF "$@"
rm -rdf "$@"
}
export -f processFiles
find . -name "filename including space"` -print0 \
| xargs -0 bash -c processFiles dummyArg > log.txt
这很简单,除了“dummyArg”让我很伤心。以这种方式运行 bash 时,参数被读入
"$0" "$1" "$2" ....
而不是预期的
"$1" "$2" "$3" ....
由于 processFiles{} 期望第一个参数是“ $1 ”,我们必须在“ $0”中插入一个虚拟值。
脚注:
另一种解决方案:
find . -name "filename including space" -print0 \
| xargs -0 -I FOUND echo "$(ls -aldF FOUND > log.txt ; rm -rdf FOUND)"