现在我们都熟悉不使用:
find . -print | xargs cmd
但使用
find . -print0 | xargs -0 cmd
为了处理包含例如换行符的文件名,但是我在脚本中的一行又如何:
find $@ -type f -print | while read filename
好吧,我以为它会是这样的:
find $@ -type f -print0 | while read -d"\0" filename
如果我只是这样做:
find $@ -type f -print0 | while read filename
我会看到 NULL 吗?
但不是,while 循环在零次后退出(在这两种情况下)我假设是因为读取返回零,我也假设因为它读取了 NULL (\0) 。
感觉就像是狂欢读应该运动“-0”选项。
我是否误读了正在发生的事情,或者是否有不同的方式来构建它?
对于这个例子,我可能必须重新编码才能使用 xargs,但这是我不想分叉的一大堆新进程。
答案1
使用 时read
,您可以使用 just-d ''
来读取下一个空字符。
从bash
手册中,关于read
内置实用程序:
-d delim
的第一个字符delim
用于终止输入行,而不是换行符。如果delim
是空字符串,read
则当读取到 NUL 字符时将终止一行。
您可能还希望设置IFS
为空字符串以停止read
修剪数据中的侧翼空格,并使用read
with-r
以便能够正确读取包含反斜杠的字符串。$@
如果您希望脚本或 shell 函数支持包含换行符、空格、文件名通配符等的搜索路径,您还需要双引号扩展:
find "$@" -type f -print0 |
while IFS= read -r -d '' pathname; do
# use "$pathname" to do something
done
find
就个人而言,如果不是迫切需要,我根本不会传递路径名,而是通过执行所需的操作-exec
,例如,
find "$@" -type f -exec sh -c '
for pathname do
# use "$pathname" to do something
done' sh {} +
相关话题: