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
    }
    
    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问题在于
      head
      读取了大量数据,然后只写了两行。当
      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"
      }
      

      请注意,默认情况下,
      read
      grep
      从stdin读取,因此无需指定
      /dev/stdin
      问题是
      head
      读取了大量数据,然后只写了两行。当
      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"
      }
      

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

      ,这确实有助于我理解发生了什么。我花在bash上的时间相对较少,所以这些小癖好通常很难根除。这真的有助于我理解正在发生的事情。我花在bash上的时间相对较少,所以这些小癖好通常很难根除。虽然我以前从未使用过awk,但这很有效,所以我不确定如何使用。你能详细解释一下吗?我添加了一些解释和一些有用的
      awk
      参考资料。虽然我以前从未使用过awk,但这是有效的,所以我不确定如何使用。你能详细解释一下我说的话吗?我已经添加了解释和一些有用的
      awk
      参考资料。