find <somebasedirectory> | \ grep stringinfilenamesIwant | \ grep -v stringinfilesnamesIdont | \ xargs dosomecommand
(或更复杂的greps组合)
近年来,find已经添加了-print0开关,而xargs已经添加了-0,这样可以通过空的终止文件名来处理具有名称空格的文件,从而允许这样做:
find <somebasedirectory> -print0 | xargs -0 dosomecommand
然而,grep(至少我的版本,Ubuntu上的GNU grep 2.10)似乎没有相当于消耗并生成空值终止的行;它具有–null,但只是直接用grep搜索文件时才使用-l来输出名称。
有没有等同的选项或组合的选项,我可以使用grep?或者,有没有一个简单而优雅的方式来表达我的命令管道,只需使用find的-regex或者Perl?
根据GNU Grep documentation,您可以使用输出行前缀控件来处理ASCII NUL字符,与find和xargs相同。
-Z
–null
Output a zero byte (the ASCII NUL character) instead of the character that normally follows a file name. For example,‘grep -lZ’ outputs a zero byte after each file name instead of the usual newline. This option makes the output unambiguous,even in the presence of file names containing unusual characters like newlines. This option can be used with commands like ‘find -print0’,‘perl -0’,‘sort -z’,and ‘xargs -0’ to process arbitrary file names,even those that contain newline characters.
使用GNU Coreutils的tr
正如OP正确指出的那样,当在输入或输出处理文件名时,这个标志是最有用的。为了将grep输出实际转换为使用NUL字符作为行尾,您需要使用像sed或tr这样的工具来转换每行输出。例如:
find /etc/passwd -print0 | xargs -0 egrep -Z 'root|www' | tr "\n" "\0" | xargs -0 -n1
这个管道将使用NUL来分离文件名,然后将换行符转换为由egrep返回的字符串中的NUL。这将通过NUL终止的字符串到管道中的下一个命令,在这种情况下,只是将输出恢复为正常字符串,但它可以是任何您想要的。