dot*_*hen 19 grep bash command-substitution process-substitution
我正在尝试针对几百个文件的列表运行 grep:
$ head -n 3 <(cat files.txt)
admin.php
ajax/accept.php
ajax/add_note.php
Run Code Online (Sandbox Code Playgroud)
但是,即使我正在搜索我知道在文件中找到的字符串,以下内容也不会搜索文件:
$ grep -i 'foo' <(cat files.txt)
$ grep -i 'foo' admin.php
The foo was found
Run Code Online (Sandbox Code Playgroud)
我熟悉从文件中-f
读取模式的标志。但是如何读取输入文件?
我曾考虑过将文件复制到cp
似乎支持该<(cat files.txt)
格式的临时目录的可怕解决方法,然后从那里 grep 文件。雪莉还有更好的办法。
ori*_*ion 32
您似乎在搜索文件名列表,而不是文件本身。<(cat files.txt)
只列出文件。尝试<(cat $(cat files.txt))
实际连接它们并将它们作为单个流进行搜索,或者
grep -i 'foo' $(cat files.txt)
Run Code Online (Sandbox Code Playgroud)
给 grep 所有文件。
但是,如果列表中的文件过多,则参数数量可能会出现问题。在那种情况下,我只会写
while read filename; do grep -Hi 'foo' "$filename"; done < files.txt
Run Code Online (Sandbox Code Playgroud)
xargs grep -i -- foo /dev/null < files.txt
Run Code Online (Sandbox Code Playgroud)
假设文件为空白或换行符分隔(其中引号或反斜杠可用于转义这些分隔符)。使用 GNU,xargs
您可以指定分隔符-d
(尽管它会禁用引用处理)。
(unset -v IFS; set -f; grep -i -- foo $(cat files.txt))
Run Code Online (Sandbox Code Playgroud)
假设文件是空格、制表符或换行符分隔的(尽管您可以通过将其分配给 来选择不同的分隔符,但无法转义这些文件IFS
)。如果大多数系统上的文件列表太大,那将失败。
那些还假设没有任何文件被调用-
。
要从 stdin 读取文件名列表,您可以使用xargs
. 例如,
cat files.txt | xargs -d'\n' grep -i -- 'foo'
Run Code Online (Sandbox Code Playgroud)
默认情况下,xargs
从标准输入读取项目,以空格分隔。该-d'\n'
告诉它使用换行符作为参数分隔符,所以它可以处理包含空格的文件名。(正如 Stéphane Chazelas 指出的那样,这是一个 GNU 扩展)。但是,它不会处理包含换行符的文件名;我们需要一个稍微复杂的方法来处理这些。
FWIW,这种方法比while read
循环要快一些,因为 bash 的read
命令非常慢 - 它逐个字符地读取其数据,而xargs
更有效地读取其输入。此外,xargs
仅grep
根据需要多次调用命令,每次调用接收多个文件名,这比grep
单独调用每个文件名更有效。
有关更多详细信息,请参阅xargs 手册页和 xargs 信息页。
xargs
可以从文件中读取项目(例如您的files.txt
列表)中读取项目:
--arg-file=file\n -a file\n Read items from file instead of standard input. If you use this\n option, stdin remains unchanged when commands are run. Other\xe2\x80\x90\n wise, stdin is redirected from /dev/null.\n
Run Code Online (Sandbox Code Playgroud)\n\n所以这也应该有效:
\n\nxargs -a files.txt grep -i 'foo'\n
Run Code Online (Sandbox Code Playgroud)\n\n或文件名中的空格
\n\nxargs -d'\\n' -a files.txt grep -i 'foo'\nxargs -I{} -a files.txt grep -i 'foo' {}\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
55063 次 |
最近记录: |