grep在功能中不起作用

时间:2018-09-11 14:35:58

标签: bash awk grep

我有一个主列表master.csv,看起来像:

line1
line2
bill, 1
sonia, 2
rhonda, 3
patty, 4

和我要过滤的名单文件:

bill
rhonda

我想保留master.txt的标头,所以我做head -n 2 master.csv >out.csv && grep -f roster.txt master.txt >>out.csv并得到:

line1
line2
bill, 1
rhonda, 3

这很棒,但是我必须一直这样做,所以我将其包装在一个函数中:

filterSections(){
    head -n 2 /dev/stdin && grep -f $1 /dev/stdin
}

因此,从理论上讲,我可以做filterSections roster.txt <master.csv >out.csv, 但我只会得到:

line1
line2

在我的大文件上,似乎只缺少第一行。谢谢

2 个答案:

答案 0 :(得分:2)

您的函数应该可以使用,但是您应该避免在stdin上放置大量数据。您可以使用以下单个awk命令来获得相同的输出:

awk -F, 'FNR==NR{seen[$1]; next} FNR <= 2 || $1 in seen' roster.txt master.csv

line1
line2
bill, 1
rhonda, 3

要将其放在函数中:

filterSections() {
    awk -F, 'FNR == NR { seen[$1]; next } FNR <= 2 || $1 in seen' "$1" "$2"
}

称呼为:

filterSections roster.txt master.csv

不好意思的解释:

  • -F,:以逗号作为输入定界符
  • FNR == NR:对于输入中的第一个文件,即roster.txt
  • { seen[$1]; next }:将$1(第一列)存储在关联数组seen中,并移至同一文件中的下一条记录
  • FNR <= 2:第二文件的记录号为<= 2
  • ||:或
  • $1 in seen:在关联数组seen中找到第二个文件的第一列

参考:

答案 1 :(得分:2)

问题在于Verify正在读取大量数据,然后仅写入2行。到head尝试从文件描述符读取时,已经没有数据了。这是一个众所周知的问题,内置的grep外壳用于处理此问题:

read

请注意,默认情况下,filterSections(){ read line # Read all characters up to first newline, and no more echo "$line" read line # Read the 2nd line, and no more echo "$line" grep -f "$1" } read是从stdin读取的,因此无需指定grep