将awk输出管道输入grep

时间:2017-05-25 06:50:56

标签: linux bash awk grep

所以我正在编写一个bash脚本,按字母顺序列出文本文件中的名称,但只列出频率相同的名称(在第二列中定义)

grep -wi '$1' /usr/local/linuxgym-data/census/femalenames.txt |
awk '{ print ($2) }' |
grep '$1' /usr/local/linuxgym-data/census/femalenames.txt |
sort |
awk '{ print ($1) }'

因为我正在上课,所以我得到了输入'ANA'的例子,应该返回

ANA

RENEE

该文件中有大约4500行

但我正在看的两个字段有

ANA            0.120     55.989    181

RENEE          0.120     56.109    182

所以我想找到第二列的所有名称与ANA(0.120)相同。第二列是名字的频率......这只是我学校给我的虚拟数据,所以我不知道这意味着什么。 但如果有另一个名称与ANA(0.120)具有相同的频率,它也会列在输出中。

当我自己运行命令时,它们工作正常,但是在第3行中使用awk输出作为$ 1在下面的grep中似乎有问题。

我对此很陌生,所以我最有可能以最迂回的方式做到这一点。

3 个答案:

答案 0 :(得分:1)

你可以在一行中做到这一点,但这是一个推动它。将其拆分为两部分,以便于编写/读取。例如:

name=$1
src=/usr/local/linuxgym-data/census/femalenames.txt

# get the frequency you're after
freq=$(awk -v name="$name" '$1==name {print $2}' "$src")

# get the names with that frequency
awk -v freq="$freq" '$2==freq {print $1}' "$src"

这与RomanPerekhrest的解决方案之间的权衡是他们的解决方案将进行一次扫描,但将内存中的所有内容编入索引。这个将扫描文件两次,但保存你的内存。

答案 1 :(得分:0)

这应该可以做到......

f="/usr/local/linuxgym-data/census/femalenames.txt"
grep $(grep -wi -m 1 "$1" $f | awk '{ print ($2) }') $f | \
  sort | awk '{ print ($1) }'

...测试

echo 'ANA            0.120     55.989    181
RENEE          0.120     56.109    182' > fem
foo() { grep $(grep -wi -m 1 "$1" $f | awk '{ print ($2) }') $f | \
         sort | awk '{ print ($1) }' ; }
f=fem ; foo ANA

输出:

ANA
RENEE

答案 2 :(得分:0)

使用单个 awk

inp="ANA"
awk -v inp=$inp '{ a[$1]=$2 } END { if(inp in a){ v=a[inp]; 
       for(i in a){ if(a[i]==v) print i }}
}' /usr/local/linuxgym-data/census/femalenames.txt | sort

输出:

ANA
RENEE
  • a[$1]=$2 - 为每个名称累积频率

  • if(inp in a){ v=a[inp]; - 如果输入名称 inp在数组中 - 获取其频率

  • for(i in a){ if(a[i]==v) print i - 打印所有名称,其频率值与输入名称相同