如何将列表文件中带有空格的文件名通过管道传输到“grep”?

如何将列表文件中带有空格的文件名通过管道传输到“grep”?

首先,我认为我使用 cygwin 的事实与这里高度相关。

理论上,我已经知道如何做到这一点:

cat file | xargs grep pattern

问题是,某些文件路径中file有空格。该文件如下所示:

subdir/foo/bar.html
subdir/f o o/ba r.html
subdir/~foo/bar.html

这会导致错误。我读到了如何解决这个问题:使用xargs -0.但我不知道如何使cat输出以空终止行结尾,所以我认为这意味着它将整个文件压缩成一行。结果,它给出了这个错误:

xargs: argument line too long

更新:事实证明,我正在读取的文件有一些不再存在的路径。巧合的是,所有这些路径都有一个~,所以我错误地认为这是一个问题。事实证明这些文件根本不存在。不过,有关空间的一切仍然存在。

答案1

xargs -d '\n'如果输入文件每行包含一个文件名,则使用。例如

xargs -d '\n' grep pattern < file

如果您的文件名以~“我的主目录”开头,则首先需要将这些~符号替换为您的实际主目录。例如:

sed -e "s=^~=$HOME=" file | xargs -d '\n' grep pattern

请注意,这个 sed 脚本是用双引号引起来的,因为我们将变量插入$HOMEsed 脚本中,并用作运算符=的分隔符,s因为$HOME将包含 /s (但不太可能包含=)。

或者,如果您使用的是find,请将 find 的-print0选项与 xargs 的-0选项结合使用。例如

find ... -print0 | xargs -0 grep pattern

或者只使用 find 的-exec选项:

find ... -exec grep pattern {} +

答案2

提到的另一个答案xargs -d '\n',这是首选解决方案。 (在我看来,这是更可取的,这是xargs应该做的默认,但那是另一个故事了。)

但并不是所有版本都xargs支持-d。如果你被一个不可行的方法所困扰,你可以尝试一下

tr '\n' '\0' < file | xargs -0 grep pattern

(曾几何时,有一些版本tr无法像这样替换空字符,但今天您不太可能遇到这些版本之一。)

答案3

请记住:xargs将把文件的全部内容作为 grep 的命令行参数...您遇到的错误可能是由于文件中的文件名太多导致命令行太长。

如果你想搜索内容匹配模式的文件,我建议使用以下迭代方法:

gcolangelo@debian-test:/tmp$ cat test_files 
/dir1/file1 with space
/dir2/file2 with space
/dir3 with space/file3

gcolangelo@debian-test:/tmp$ while read filepath ; do echo "-- coin ${filepath} --" ; done < test_files 
-- coin /dir1/file1 with space --
-- coin /dir2/file2 with space --
-- coin /dir3 with space/file3 --
-- coin  --

答案4

在某些情况下,使用while循环可能会更好xargs(例如,当您想要执行多个命令时):

while IFS= read -r file <&3
do
    grep -- pattern "$file" 3<&-
done 3< file

grep但请注意,它会为每个文件调用一个。

相关内容