迭代Bash脚本Bug

时间:2018-03-16 06:58:18

标签: linux bash shell awk grep

使用bash脚本,我试图遍历一个文本文件,该文件只有大约700个单词,逐行,并在当前目录中使用特定文件上的该字运行不区分大小写的grep搜索。为了分解它,我正在尝试将以下内容输出到文件中:

  
      
  1. 在文件中添加换行符,然后在搜索到的单词后面添加换行符,然后添加另一个换行符
  2.   
  3. 使用该搜索附加grep命令的结果
  4.   
  5. 重复步骤1和2,直到列表中的所有单词都用完为止
  6.   

例如,如果我有这个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"

然而,由于某种原因,这(以及我尝试过的众多变种)无效。看起来微不足道,但我确实令我感到沮丧。任何帮助表示赞赏。

3 个答案:

答案 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)

可能出现的问题:

  1. bash路径 - 使用/bin/bash路径代替/usr/bin/bash
  2. 空格 - 在' '
  3. 之后删除IFS
  4. echo - 使用-e选项处理转义字符(此处为:'\n'
  5. 分号 - 行尾不需要
  6. 尝试以下脚本:

    #!/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