为什么grep无法过滤shell脚本中的右行?

时间:2017-10-12 11:09:57

标签: shell grep

代码如下:

#!/bin/bash

file=$(cat b.txt | tr "[:upper:]" "[:lower:]" | tr -c "[:alnum:]" '\n' | grep -v "^$")

cat a.txt | while read line; do
    file=$(echo "$file" | grep -ov "$line")
done
echo "$file" | sort | uniq -c | sort -n

以上 a.txt 是一个带有段落的文件, b.txt 是每行都有一些单词的文件,我只想删除<来自 a.txt 的strong> b.txt ,但答案是错误的。

例如:

b.txt

Hello, i want to go to school

A.TXT

hello
i

预期结果:

  1 go
  1 school
  1 want
  2 to

实际结果:

  1 go
  1 hello
  1 i
  1 school
  1 want
  2 to

虽然我的回答还包括b.txt中包含的单词。

2 个答案:

答案 0 :(得分:3)

这是由于无用的猫造成的经典子shell变量问题。由于您将cat连接到while循环并且管道在子shell中运行,因此变量file的赋值仅影响子shell。原始变量未被修改。最简单的解决方案是编写while read line; do ... done < a.txt

第二种解决方案是从子shell中回显变量:

cat a.txt | { while read line; do
    file=$(echo "$file" | grep -ov "$line")
done
echo "$file" | sort | uniq -c | sort -n
}

答案 1 :(得分:1)

AWK 方法:

awk 'BEGIN {
    FS="[,[:space:]]";
}
{
    if (NR==FNR) {
        for(i=1;i<=NF;++i){
            black[tolower($i)]=1;
        }
        next;
    }
    for (i=1; i<=NF; ++i) {
        if ($i && black[tolower($i)]!=1) {
            target[tolower($i)]+=1;
        }
    }
}
END {
    for (i in target) {
        print target[i], i;
    }
}' a.txt b.txt

<强>输出

1 want
1 go
2 to
1 school