首先,我认为我使用 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 脚本是用双引号引起来的,因为我们想将变量插入$HOME
sed 脚本中,并用作运算符=
的分隔符,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
但请注意,它会为每个文件调用一个。