我有一个文本文件目录,每个文件都包含一行"功能号码:"接着是一些数字。我还有另一个文本文件,其中包含我想要搜索它们的顺序的文件名列表。我尝试了以下bash命令:
while read LINE; do
grep -i 'feature number' $LINE > outputFile.txt
done < ../listOfFiles.txt
但从未收到任何输出。
grep -f ../listOfFiles.txt p*.txt
也没有返回任何内容,但
read LINE < ../listOfFiles.txt; echo $LINE
确实如此
grep -i 'feature number' oneOfTheFiles.txt
确实如此。
该命令的哪一部分无效,我该如何解决?
答案 0 :(得分:3)
提供答案,总结评论意见中的所有有用提示:
@fedorqui 指出在循环中使用>
,在每次迭代中覆盖输出文件循环,因此实际上只在输出文件中捕获 last 迭代的输出。
立即修复是使用>>
,而将附加到现有输出文件(或创建它,如果它不存在)。
while read -r LINE; do
grep -i 'feature number' "$LINE" >> outputFile.txt
done < ../listOfFiles.txt
请注意,我还使代码段更加强大:
read -r
确保在不解释\
字符的情况下读取输入行。 - 但是,从每一行修剪前导和尾随空格。"$LINE"
现在是双引号,以防止它被shell扩展;例如,如果变量值包含空格,则这是必要的。但是, >>
会附加到任何预先存在的 outputFile.txt
,因此,如果您多次运行该代码段,则该文件会保留越来越大。
为防止这种情况发生,您可以事先明确截断(: >outputFile.txt
)或删除(rm -f outputFile.txt
)输出文件,或者最好利用@konsoelbox推荐的简化< /强>:
while read -r LINE; do
grep -i 'feature number' "$LINE"
done < ../listOfFiles.txt > outputFile.txt
通过将输出重定向 - >
- 置于while
循环的 end ,所有次迭代的输出为作为一个整体捕获,同时替换任何已存在的文件。
最后, @tripleee 建议使用xargs
代替while
循环的更彻底的简化:
xargs grep -h -i 'feature number' < ../listOfFiles.txt > outputFile.txt
这将(通常)导致 单个调用grep
,所有输入行作为文件名参数传递。< / p>
除了缩短写作时,这种方法效率更高
请注意使用grep -h
,它会禁止匹配前缀与原始文件的名称。
警告:只要../listOfFiles.txt
中的文件名没有嵌入空格,此就可以正常运行,因为每个此类文件名都会被拆分为多个参数。
正确处理包含空格的文件名:
如果您有 GNU xargs
,请使用-d'\n'
以确保在传递给{时将每一行视为自己的参数{1}}:
grep
如果您只有 POSIX兼容 xargs -d'\n' grep -h -i 'feature number' < ../listOfFiles.txt > outputFile.txt
:使用xargs
,但这意味着每个输入行都会为-I
调用 。
grep
最后,如果你有一个支持xargs -I % grep -i 'feature number' % < ../listOfFiles.txt > outputFile.txt
的 xargs
版本来处理NUL分隔的输入(例如,GNU -0
,FreeBSD( OSX)xargs
),您可以使用以下技巧:
xargs
请注意,基于xargs -0 grep -h -i 'feature number' \
< <(tr '\n' '\0' < ../listOfFiles.txt) > outputFile.txt
的方法通常是最强大的方法,因为它甚至支持具有嵌入式-0
字符的参数。但是NUL分离的输入并不总是随时可用,因为需要\n
技巧演示。
答案 1 :(得分:-1)
grep命令应该是这样的:
grep -inr&#34;搜索字符串&#34;