首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >迭代Bash脚本Bug

迭代Bash脚本Bug
EN

Stack Overflow用户
提问于 2018-03-16 06:58:17
回答 3查看 203关注 0票数 0

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

  1. 将换行符追加到文件中,然后是搜索的单词,然后是另一行
  2. 使用该搜索追加grep命令的结果。
  3. 重复步骤1和步骤2,直到列表中的所有单词都用完为止。

例如,如果我有这个list.txt:

代码语言:javascript
代码运行次数:0
运行
复制
search1
search2

我希望results.txt是:

代码语言:javascript
代码运行次数:0
运行
复制
search1:
grep result here

search2:
grep result here

在整个堆栈交换过程中,我找到了一些关于如何做到这一点的答案,并提出了以下实现:

代码语言:javascript
代码运行次数:0
运行
复制
#!/usr/bin/bash

while IFS = read -r line;
do 
    "\n$line:\n" >> "results.txt";
    grep -i "$line" *.in >> "results.txt";
done < "list.txt"

然而,由于某些原因(以及我尝试过的众多变体)无法工作。似乎微不足道,但我会一直令我难以置信。任何帮助都是非常感谢的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-16 12:07:38

如果将脚本更改为:

代码语言:javascript
代码运行次数:0
运行
复制
while IFS= read -r line; do
    printf '\n%s:\n' "$line"
    grep -i "$line" *.in
done < list.txt > results.txt

但它会非常慢。请参阅https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice,了解为什么在编写shell循环之前,您应该考虑很长时间,然后才能操作文本。操纵文本的标准UNIX工具是awk:

代码语言:javascript
代码运行次数:0
运行
复制
awk '
NR==FNR { words2matches[$0]; next }
{
    for (word in words2matches) {
        if ( index(tolower($0),tolower(word)) ) {
            words2matches[word] = words2matches[word] $0 ORS
        }
    }
}
END {
    for (word in words2matches) {
        print word ":" ORS words2matches[word]
    }
}
' list.txt *.in > results.txt

当然,上面的内容没有经过测试,因为您没有提供我们可以进行测试的示例输入/输出。

票数 1
EN

Stack Overflow用户

发布于 2018-03-16 07:20:43

可能出现的问题:

  1. bash路径-使用/bin/bash路径而不是/usr/bin/bash
  2. 空格-删除' '后的IFS
  3. 使用-e选项处理转义字符(此处:'\n')
  4. 分号-行尾不需要分号

请尝试使用以下脚本:

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash

while IFS= read -r line; do
    echo -e "$line:\n" >> "results.txt"
    grep -i "$line" *.in >> "results.txt"
done < "list.txt"
票数 0
EN

Stack Overflow用户

发布于 2018-03-16 08:52:55

甚至不需要为此目的编写bash脚本:

输入文件:

代码语言:javascript
代码运行次数:0
运行
复制
$ more file?.in
::::::::::::::
file1.in
::::::::::::::
abc
search1
def
search3
::::::::::::::
file2.in
::::::::::::::
search2
search1
abc
def
::::::::::::::
file3.in
::::::::::::::
abc
search1
search2
def
search3

模式文件:

代码语言:javascript
代码运行次数:0
运行
复制
$ more patterns 
search1
search2
search3

CMD:

代码语言:javascript
代码运行次数:0
运行
复制
$ 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}'

输出:

代码语言:javascript
代码运行次数:0
运行
复制
search1
file1.in:2
file2.in:2
file3.in:2
search2
file2.in:1
file3.in:3
search3
file1.in:4
file3.in:5

EXPLANATIONS:

  • grep -inf patterns file*.in将grep所有file*.in与所有模式位于模式文件中感谢-f选项,使用-i强制不敏感大小写,-n将添加行号
  • sort -t':' -k3使用第三列对输出进行排序,以便将模式重新组合在一起
  • awk -F':' 'BEGIN{OFS=FS}{if($3==buffer){print $1,$2}else{print $3; print $1,$2}buffer=$3}'然后awk将打印您想要的显示,方法是使用:作为字段分隔器和输出字段分隔器,使用缓冲区变量保存模式(第三个字段),并在模式更改时打印模式($3!=buffer)。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49314856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档