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

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

你的函数应该可以工作,但你应该避免在标准上放置大量数据。您可以使用此单个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

awk解释:

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

引用:

  • 有效的 AWK 编程
  • awk 教程

问题是head正在读取大量数据,然后只写入 2 行。 当grep尝试从文件描述符中读取时,已经没有数据了。 这是一个众所周知的问题,shell 内置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"
}

请注意,默认情况下readgrep从 stdin 读取,因此无需指定/dev/stdin

最新更新