Bash and filenames with spaces

前端 未结 6 1800
情深已故
情深已故 2020-12-01 03:23

The following is a simple Bash command line:

grep -li \'regex\' \"filename with spaces\" \"filename\"

No problems. Also the following works

6条回答
  •  悲&欢浪女
    2020-12-01 03:33

    cat listOfFiles.txt |tr '\n' '\0' |xargs -0 grep -li 'regex'
    

    The -0 option on xargs tells xargs to use a null character rather than white space as a filename terminator. The tr command converts the incoming newlines to a null character.

    This meets the OP's requirement that grep not be invoked multiple times. It has been my experience that for a large number of files avoiding the multiple invocations of grep improves performance considerably.

    This scheme also avoids a bug in the OP's original method because his scheme will break where listOfFiles.txt contains a number of files that would exceed the buffer size for the commands. xargs knows about the maximum command size and will invoke grep multiple times to avoid that problem.

    A related problem with using xargs and grep is that grep will prefix the output with the filename when invoked with multiple files. Because xargs invokes grep with multiple files one will receive output with the filename prefixed, but not for the case of one file in listOfFiles.txt or the case of multiple invocations where the last invocation contains one filename. To achieve consistent output add /dev/null to the grep command:

    cat listOfFiles.txt |tr '\n' '\0' |xargs -0 grep -i 'regex' /dev/null
    

    Note that was not an issue for the OP because he was using the -l option on grep; however it is likely to be an issue for others.

提交回复
热议问题