如何在 shell 中拆分 NUL
我使用 zsh 作为 shell。
我想执行 unix find 命令并将结果放入 shell 数组变量中,例如:
FILES=($(find . -name '*.bak'))
这样我就可以使用类似的内容迭代这些值
for F in "$FILES[@]"; do echo "<<$F>>"; done
但是,我的文件名至少包含空格,也许还包含其他时髦字符,因此上面不起作用。 有效的是:
IFS=$(echo -n -e "\0"); FILES=($(find . -name '*.bak' -print0)); unset IFS
但这很丑陋。 这已经有点超出了我对 zsh 语法的舒适极限,所以我希望有人能向我指出一些我从来不知道但应该知道的基本功能。
I am using zsh as a shell.
I would like to execute the unix find command and put the result into a shell array variable, something like:
FILES=($(find . -name '*.bak'))
so that I can iterate over the values with something like
for F in "$FILES[@]"; do echo "<<$F>>"; done
However, my filenames contain spaces at least, and perhaps other funky characters, so the above doesn't work. What does work is:
IFS=$(echo -n -e "\0"); FILES=($(find . -name '*.bak' -print0)); unset IFS
but that's fugly. This is already a bit beyond my comfort limit with zsh syntax, so I'm hoping someone can point me to some basic feature that I never knew about but should.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我倾向于使用
read
来实现这一点。 快速的谷歌搜索显示 zsh 似乎也支持这一点:它不会以零字节分割,但它可以处理包含除换行符之外的空格的文件名。 如果文件名出现在要执行的命令的最后,您可以使用 xargs,也可以使用文件名中的换行符:
将找到的所有文件复制到目录
/tmp/dst 中
。 当然,xargs 方法的缺点是变量中没有文件名。 所以这并不总是适用。I tend to use
read
for that. A quick google search showed me zsh also seem to support that:That doesn't split with zero bytes, but it will make it work with file-names containing whitespace other than newlines. If the file-name appears at the very last of the command to be executed, you can use
xargs
, working also with newlines in filenames:copies all files found into the directory
/tmp/dst
. Downside of the xargs approach is that you don't have the filenames in a variable, of course. So this not always applicable.我发现的唯一方法是使用 eval:
用法:
SplitAt0 varname command [arguments]
我应该使用
\0''.)F} )' (zyx:~/tmp) % echo $F[1] ./ 0${(ps.\0.)F}
,而不是${(s.\0.)F}
:${(s.\0.)...} 和 ${(s.$'\0'.)...} 不起作用。
您可以使用函数:
用法:
SplitAt0 varname command [arguments]
我应该使用
${(ps.\0.)F}
,而不是${(s.\0.)F}
:The only way I figured out is using eval:
Usage:
SplitAt0 varname command [arguments]
I should have used
\0''.)F} )' (zyx:~/tmp) % echo $F[1] ./ 0${(ps.\0.)F}
, not${(s.\0.)F}
:${(s.\0.)...} and ${(s.$'\0'.)...} do not work.
You can use function:
Usage:
SplitAt0 varname command [arguments]
I should have used
${(ps.\0.)F}
, not${(s.\0.)F}
:或者,由于您使用的是 zsh,因此可以使用 zsh 的扩展通配语法来查找文件,而不是使用 find 命令。 据我所知, find 的所有功能都存在于通配语法中,并且它可以正确处理带有空格的文件名。 有关详细信息,请参阅
zshexpn(1)
联机帮助页。 如果您全职使用 zsh,那么学习其语法是非常值得的。Alternatively, since you're using zsh, you can use zsh's extended globbing syntax to find files rather than using the find command. As far as I know, all the functionality of find is present in the globbing syntax, and it handles filenames with whitespaces properly. See the
zshexpn(1)
manpage for more info. If you use zsh on a fulltime basis, it's well worth learning the syntax.我已经尝试过了
,它甚至可以处理文件名中带有换行符的文件。
I've tried
and it handles even the files with newlines in the filename.