在文件名中包含空格的文件中搜索(使用)grep

3

我有一个包含文件名的列表。其中一些文件名包含空格:

./folder/folder/some file name.ext

我需要对这些文件进行grep操作:

cat filelist | while read i; do grep "pattern" $i; done

显然grep因为空格而失败:

grep ./folder/folder/some: No such file or directory
grep file: No such file or directory
grep name: No such file or directory

我尝试过转义空格,例如:
:%s/some file name/some\ file\ name/g

但是没有运气。我该如何执行我的操作?谢谢!


你能用\s代替吗? - Unihedron
1
可能是将文件列表传递给grep的重复问题。 - Tom Fenech
4个回答

6
你可以使用这个循环:
while read -r i; do grep "pattern" "$i"; done < filelist

使用管道与cat一起使用容易出错,而且BASH会将含有空格的字符串视为独立的参数。

3
我认为使用 cat 并不是问题。实际上,问题本身在于 $i 没有用 "" 引起来,导致出现了单词拆分。 - konsolebox

6

如果使用xargs,会更加简单:

xargs -d '\n' -- grep pattern -- < filelist

如果你需要每个 grep 实例只处理一个文件,那么请添加 -n 1

xargs -n 1 -d '\n' -- grep pattern -- < filelist

您也可以使用readarray
readarray -t files < filelist
for f in "${files[@]}"; do grep pattern -- "$f"; done

或者简单地说
readarray -t files < filelist
grep pattern -- "${files[@]}"

请确保文件格式为UNIX格式:

sed -i 's|\r||' filelist  ## Or
dos2unix filelist

您可以直接使用进程替换来完成:

readarray -t files < <(exec sed -e 's|\r||' filelist)
xargs -d '\n' -- grep pattern -- < <(exec sed -e 's|\r||' filelist)

两者之间有什么区别? - Tom Fenech
@TomFenech 前者严格遵循每个实例处理一个文件的方法。 - konsolebox
1
xargs 模式比 whilefor 循环效率高得多。想象一下,您正在对一百万个文件的列表进行 grep - 每个文件都将使用 while/for 循环打开、读取和关闭。我花了几个小时才在列表的 10% 或更少的范围内进行 grep。 而使用 xargs,我在几分钟内就完成了更多工作。 - kK-Storm
@kK-Storm 每个文件都将使用 xargs 打开。唯一的区别(显着的)是执行更少的 grep 实例 - 除非你加上 -n 1 - konsolebox

1

引用 $i

cat filelist | while read i; do grep "pattern" "$i"; done

0

简单高效:

var=$(awk '{ print "\""$0"\""}' filelist)
command="grep \"pattern\" $var"
eval $command

或者如果你想要它成为一行代码:

command="grep -ir \"pattern\" $(awk '{ print "\""$0"\""}' <<< "$(ls)")"; eval $command

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接