使用bash脚本,我试图遍历一个文本文件,该文件只有大约700个单词,逐行,并在当前目录中使用特定文件上的该字运行不区分大小写的grep搜索。为了分解它,我正在尝试将以下内容输出到文件中:
- 在文件中添加换行符,然后在搜索到的单词后面添加换行符,然后添加另一个换行符
- 使用该搜索附加grep命令的结果
- 重复步骤1和2,直到列表中的所有单词都用完为止
醇>
例如,如果我有这个list.txt:
search1
search2
我希望results.txt为:
search1:
grep result here
search2:
grep result here
我在堆栈交换中找到了一些关于如何做到这一点的答案,并提出了以下实现:
#!/usr/bin/bash
while IFS = read -r line;
do
"\n$line:\n" >> "results.txt";
grep -i "$line" *.in >> "results.txt";
done < "list.txt"
然而,由于某种原因,这(以及我尝试过的众多变种)无效。看起来微不足道,但我确实令我感到沮丧。任何帮助表示赞赏。
答案 0 :(得分:1)
如果您将脚本更改为:
,那么您的脚本将会有效-F
但它非常慢。请参阅https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice,了解为什么在编写shell循环之前应该仔细思考以便操作文本。用于操作文本的标准UNIX工具是awk:
while IFS= read -r line; do
printf '\n%s:\n' "$line"
grep -i "$line" *.in
done < list.txt > results.txt
上述情况当然未经测试,因为您没有提供我们可以测试的样本输入/输出。
答案 1 :(得分:0)
可能出现的问题:
/bin/bash
路径代替/usr/bin/bash
' '
IFS
-e
选项处理转义字符(此处为:'\n'
)尝试以下脚本:
#!/bin/bash
while IFS= read -r line; do
echo -e "$line:\n" >> "results.txt"
grep -i "$line" *.in >> "results.txt"
done < "list.txt"
答案 2 :(得分:0)
您甚至不需要为此目的编写bash脚本:
输入文件:
$ more file?.in
::::::::::::::
file1.in
::::::::::::::
abc
search1
def
search3
::::::::::::::
file2.in
::::::::::::::
search2
search1
abc
def
::::::::::::::
file3.in
::::::::::::::
abc
search1
search2
def
search3
PATTERN FILE:
$ more patterns
search1
search2
search3
<强> CMD:强>
$ grep -inf patterns file*.in | sort -t':' -k3 | awk -F':' 'BEGIN{OFS=FS}{if($3==buffer){print $1,$2}else{print $3; print $1,$2}buffer=$3}'
<强>输出:强>
search1
file1.in:2
file2.in:2
file3.in:2
search2
file2.in:1
file3.in:3
search3
file1.in:4
file3.in:5
<强>解释:强>
grep -inf patterns file*.in
将使用-f
选项grep所有文件* .in以及所有模式位于模式文件中,使用-i
强制不敏感的情况,-n
将添加行号sort -t':' -k3
您使用第3列对输出进行排序以将模式重新组合在一起awk -F':' 'BEGIN{OFS=FS}{if($3==buffer){print $1,$2}else{print $3; print $1,$2}buffer=$3}'
然后awk
将使用:
作为字段分隔符和输出字段分隔符打印所需的显示,使用缓冲区变量来保存模式(第3个字段)和每当模式发生变化时都会打印模式($3!=buffer
)