【问题标题】:Pass a list of files to grep将文件列表传递给 grep
【发布时间】:2013-11-05 15:56:41
【问题描述】:

我有一个文件列表。列表很大,而且文件名是非标准的:这意味着,有些有空格、非 ascii 字符、引号、单引号......

因此,将 huge 文件列表作为参数传递给 grep 不是一种选择:

  • 因为我不确定我会不会超过 linux 中允许的参数长度。不过,我想我可以通过使用xargs 划分参数来解决这个问题。
  • 因为转义这些字符很复杂。如果我想用双引号将文件名括起来,而该文件名恰好有双引号,我就有麻烦了。所以我需要转义一些字符。整个事情看起来很复杂,我不想走那条路。

必须有一个更简单的方法:我如何告诉 grep 使用我的文件列表作为 grep 的文件?我假设由于 shell 不会处理文件列表,因此转义和参数长度不再是问题。问题是grep是否支持这种操作模式,我在文档中一直找不到。

【问题讨论】:

  • 这样的事情不应该对你有用吗? while read file; do grep .... "$file" done < your_file_list 注意"$file" 以允许文件名中有空格。
  • 不确定如果文件有双引号会发生什么......我知道这很奇怪,但有可能(文件系统支持)

标签: grep


【解决方案1】:

据我所知,GNU grep 不支持这个。你有几个选择。

使用 bash 循环解析文件列表

这是@fedorqui 提供的解决方案

while read file; do 
    grep "$PATTERN" "$file" 
done < file_with_list_of_files

使用 xargs 一次将多个文件传递给 grep

这里我告诉 xargs 将 10 个文件名传递给 grep

PATTERN='^$' # searching for blank lines
xargs -n 10 -d '\n' grep "$PATTERN" < file_with_list_of_files

使用 xargs 一次将多个文件传递给 grep,处理文件名中的换行符

如上,但使用空终止行

PATTERN='^$' # searching for blank lines
tr '\n' '\0' file_with_list_of_files
xargs -n 10 -0 grep "$PATTERN" < file_with_list_of_files

编辑:正确处理空格 Edit2:删除产生乱码输出的示例,添加处理换行符的示例

【讨论】:

  • 谢谢!第一个选项可能太慢了(每个文件都有一个新的 grep 进程)。第三个可能会产生乱码输出(多个进程并行写入标准输出?)。第二个可能是我将使用的。我会告诉你进展如何。
  • 一个问题:xargs 是否可以正确处理任何文件名,包括带有 unicode 字符的文件名,或者像双引号这样的意外字符? xargs 期望的格式是什么?我假设每行一个文件。如何使用嵌入的换行符指定文件名? (奇怪,但文件系统允许这样做)
  • 我现在看到-d 指定了分隔符。我已经使用带有 very 奇怪字符的文件名测试了您的方法,并且它完美地工作(即使对于双引号、单引号、空格、任何 unicode 字符,...)。我唯一无法支持的是嵌入式换行符,因为在这种情况下我不知道如何生成文件列表(因为换行符按原样放在 lof 中,然后 xargs 假定两个不同的文件)。这种极端情况将不受支持。
  • xargs 支持使用 -0 标志以空字符结尾的字符串,如果您以空字符结尾的文件名列表,这可能会处理嵌入的换行符的情况。尝试tr '\n' '\0' list_of_files 以这种格式获取您的输入列表
  • 使用 -H 标志和 grep 以文件名作为输出前缀,就像使用 -r 时一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-27
  • 2020-08-09
  • 1970-01-01
  • 2016-07-24
相关资源
最近更新 更多