【问题标题】:gsub with awk on a file by namegsub 与 awk 按名称在文件上
【发布时间】:2020-01-13 12:57:54
【问题描述】:

我正在尝试学习如何将 awk 与 gsub 一起用于特定字段,但传递的是名称,而不是此数据上的列号:

especievalida,nom059
Rhizophora mangle,Amenazada (A)
Avicennia germinans,Amenazada (A)
Laguncularia racemosa,Amenazada (A)
Cedrela odorata,Sujeta a protección especial (Pr)
Litsea glaucescens,En peligro de extinción (P)
Conocarpus erectus,Amenazada (A)
Magnolia schiedeana,Amenazada (A)
Carpinus caroliniana,Amenazada (A)
Ostrya virginiana,Sujeta a protección especial (Pr)

我试过了

awk -F, -v OFS=","   '{gsub("\\(.*\\)", "", $2 ) ; print $0}' 

删除第二列 ($2) 括号之间的所有内容;但我真的很希望能够将“nom059”传递给表达式,以获得相同的结果

【问题讨论】:

    标签: bash awk gsub


    【解决方案1】:

    在读取输入文件的第一行(标题行)时,构建一个将字段名称映射到字段编号的数组(下面的f[])。然后,您可以通过将它们的名称作为f[] 的索引来访问这些字段,以获取它们的编号和内容:

    $ cat tst.awk
    BEGIN {
        FS = OFS = ","
    }
    NR==1 {
        for (i=1; i<=NF; i++) {
            f[$i] = i
        }
    }
    {
        gsub(/\(.*\)/,"",$(f["nom05"]))
        print
    }
    
    $ awk -f tst.awk file
    especievalida,nom059
    Rhizophora mangle,Amenazada
    Avicennia germinans,Amenazada
    Laguncularia racemosa,Amenazada
    Cedrela odorata,Sujeta a protección especial
    Litsea glaucescens,En peligro de extinción
    Conocarpus erectus,Amenazada
    Magnolia schiedeana,Amenazada
    Carpinus caroliniana,Amenazada
    Ostrya virginiana,Sujeta a protección especial
    

    顺便说一句,阅读https://www.gnu.org/software/gawk/manual/gawk.html#Computed-Regexps,了解为什么应该使用gsub(/.../(常量或文字正则表达式)而不是gsub("..."(动态或计算的正则表达式)。

    【讨论】:

      【解决方案2】:

      请您尝试以下操作。我创建了一个名为 header_valueawk 变量,您可以在其中提及要使用 gsub 的字段名称。

      awk -v header_value="nom059" '
      BEGIN{
        FS=OFS=","
      }
      FNR==1{
        for(i=1;i<=NF;i++){
           if($i==header_value){
               field_value=i
           }
        }
        print
        next
      }
      {
        gsub(/\(.*\)/, "",$field_value)
      }
      1
      '  Input_file
      

      解释:添加上述代码的解释。

      awk -v header_value="nom059" '           ##Starting awk program here and creating a variable named header_value whose value is set as nom059.
      BEGIN{                                   ##Starting BEGIN section of this program here.
        FS=OFS=","                             ##Setting FS and OFS value as comma here.
      }                                        ##Closing BEGIN section here.
      FNR==1{                                  ##Checking condition if FNR==1, line is 1st line then do following.
        for(i=1;i<=NF;i++){                    ##Starting a for loop which starts from i=1 to till value of NF.
           if($i==header_value){               ##checking condition if any field value is equal to variable header_value then do following.
               field_value=i                   ##Creating variable field_value whose value is variable i value.
           }
        }
        print                                  ##Printing 1st line here.
        next                                   ##next will skip all further statements from here.
      }
      {
        gsub(/\(.*\)/, "",$field_value)        ##Now using gsub to Globally  substituting everything between ( to ) with NULL in all lines.
      }
      1                                        ##Mentioning 1 will print edited/non-edited line.
      '  Input_file                            ##Mentioning Input_file name here.
      

      【讨论】:

      • 为每个字段创建一个单独的变量(例如field_value)如果您只有一个您感兴趣的字段但创建一个将所有字段名称映射到其位置的数组(例如f[])是可以的如在stackoverflow.com/a/57893381/1745001 中使用的那样,对于这种最小情况同样适用,因为它适用于您需要按名称访问数十个字段的情况,它可以让您轻松循环所有字段和/或测试存在的字段名称如果需要,这通常是更好的方法。
      • @EdMorton,感谢 Ed 先生的反馈,指出了一点,将来会尝试实施,干杯。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 2019-04-21
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      相关资源
      最近更新 更多