Bash grep在函数中不起作用
我有一个主列表,Bash grep在函数中不起作用,bash,awk,grep,Bash,Awk,Grep,我有一个主列表,master.csv,看起来像: line1 line2 bill, 1 sonia, 2 rhonda, 3 patty, 4 还有一个我想筛选的名册文件: bill rhonda 我想保留master.txt的标题,所以我做了head-n2 master.csv>out.csv&&grep-f lotster.txt master.txt>>out.csv,我得到: line1 line2 bill, 1 rhonda, 3 这很好,但我必须一直这样做,所以我将其包装在
master.csv
,看起来像:
line1
line2
bill, 1
sonia, 2
rhonda, 3
patty, 4
还有一个我想筛选的名册文件:
bill
rhonda
我想保留master.txt
的标题,所以我做了head-n2 master.csv>out.csv&&grep-f lotster.txt master.txt>>out.csv
,我得到:
line1
line2
bill, 1
rhonda, 3
这很好,但我必须一直这样做,所以我将其包装在一个函数中:
filterSections(){
head -n 2 /dev/stdin && grep -f $1 /dev/stdin
}
filterSections() {
awk -F, 'FNR == NR { seen[$1]; next } FNR <= 2 || $1 in seen' "$1" "$2"
}
因此,理论上,我可以做filterSections-lotster.txt out.csv
,
但我只得到:
line1
line2
在我的大文件中,它似乎只缺少第一行。谢谢您的函数应该可以工作,但是您应该避免在stdin上放置大量数据。您可以使用此单个
awk
命令获得相同的输出:
awk -F, 'FNR==NR{seen[$1]; next} FNR <= 2 || $1 in seen' roster.txt master.csv
要将其放入函数中,请执行以下操作:
filterSections(){
head -n 2 /dev/stdin && grep -f $1 /dev/stdin
}
filterSections() {
awk -F, 'FNR == NR { seen[$1]; next } FNR <= 2 || $1 in seen' "$1" "$2"
}
awk解释:
:将逗号作为输入分隔符-F,
:对于输入中的第一个文件,即FNR==NR
花名册.txt
:在关联数组{seen[$1];next}
中存储seen
(第1列),并移动到同一文件中的下一条记录$1
FNR您的函数应该可以工作,但是您应该避免在stdin上放置大量数据。您可以使用此单个
命令获得相同的输出:awk
要将其放入函数中,请执行以下操作:awk -F, 'FNR==NR{seen[$1]; next} FNR <= 2 || $1 in seen' roster.txt master.csv
filterSections(){ head -n 2 /dev/stdin && grep -f $1 /dev/stdin }
awk解释:filterSections() { awk -F, 'FNR == NR { seen[$1]; next } FNR <= 2 || $1 in seen' "$1" "$2" }
:将逗号作为输入分隔符-F,
:对于输入中的第一个文件,即FNR==NR
花名册.txt
:在关联数组{seen[$1];next}
中存储seen
(第1列),并移动到同一文件中的下一条记录$1
FNR问题在于
读取了大量数据,然后只写了两行。当head
尝试从文件描述符读取时,已经没有数据了。这是一个众所周知的问题,shell内置的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
问题是/dev/stdin
读取了大量数据,然后只写了两行。当head
尝试从文件描述符读取时,已经没有数据了。这是一个众所周知的问题,shell内置的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
,这确实有助于我理解发生了什么。我花在bash上的时间相对较少,所以这些小癖好通常很难根除。这真的有助于我理解正在发生的事情。我花在bash上的时间相对较少,所以这些小癖好通常很难根除。虽然我以前从未使用过awk,但这很有效,所以我不确定如何使用。你能详细解释一下吗?我添加了一些解释和一些有用的/dev/stdin
参考资料。虽然我以前从未使用过awk,但这是有效的,所以我不确定如何使用。你能详细解释一下我说的话吗?我已经添加了解释和一些有用的awk
参考资料。awk