【问题标题】:HOw to add new column from another file in awk如何在 awk 中从另一个文件添加新列
【发布时间】:2015-05-08 11:45:03
【问题描述】:

我有两个如下所示的以​​制表符分隔的文件:

文件 A

123,789   aa b c d
123       aa b c d
234       a  b c d
345       aa b c d
456       a  b c d
....

文件B

123    add    c    d    e
345    add   e    f    g
789    sub   e    f    g
...

我想根据第 1 列将文件 B 中的第 2 列添加到文件 A 中,以便输出如下所示: 输出:

123,789   add,sub  aa b c d
123        add     aa b c d
234                a  b c d
345        add     aa b c d
456                a  b c d
....

我尝试使用:

awk 'NR==FNR{a[$1]=$2;next}{$2=a[$1]FS$2;print}' OFS='\t' fileB file A

给出输出:

123,789            aa b c d
123        add     aa b c d
234                a  b c d
345        add     aa b c d
456                a  b c d

问题在于文件 A 的 column1 中的列具有多个用逗号分隔的字符串。awk 代码将其视为单个字符串,因此无法与 fileB 匹配。有人可以对 awk 代码进行编辑或任何修复。谢谢。

【问题讨论】:

    标签: linux awk


    【解决方案1】:

    我会说

    awk -F '\t' 'BEGIN { OFS = FS } NR == FNR { saved[$1] = $2; next } { n = split($1, a, ","); sep = ""; field = ""; for(i = 1; i <= n; ++i) { if(a[i] in saved) { field = field sep saved[a[i]]; sep = "," } } $1 = $1 OFS field } 1' fileB fileA
    

    即:

    BEGIN { OFS = FS }                  # Output separated like input
    
    NR == FNR {                         # while processing fileB:
      saved[$1] = $2                    # just remember stuff
      next
    }
    
    {                                   # while processing fileA:
      n = split($1, a, ",")             # split first field at commas
    
      sep   = ""                        # reset temps
      field = ""
    
      for(i = 1; i <= n; ++i) {         # wade through comma-separated parts of $1
        if(a[i] in saved) {             # if a corresponding line existed in fileB
          field = field sep saved[a[i]] # append it to the new field
          sep = ","                     # from the second forward, separate by ","
        }
      }
    
      $1 = $1 OFS field                 # insert the new field into the line
    }
    1                                   # then print.
    

    【讨论】:

    • 和我的基本一样,但是有完整的解释。随意从我的中获取您喜欢的任何内容 - 我建议将第三个参数更改为 split 为 /,/。另外我认为重点是覆盖第二个字段而不是在它之前插入新字段。只需将field 更改为$2 即可。
    • @TomFenech aa 字段仍然出现在示例输出中。除非我是盲人(诚然,这并非没有先例),否则应该插入一个新字段。 /,/ 对我来说似乎是一个品味问题。我想可以提出一个论点,即/,/ 使split 的论点是一个正则表达式更加明显,但我主观上认为它的可读性较差。
    • 啊,是的,插入字段是对的。我想支持使用正则表达式的论点是,您可以节省可怜的 awk,而不必为您转换字符串,这会花费几个周期:-)
    • 我希望大多数 awk 在开始时只做一次。这些天我可能应该对它进行基准测试。
    • 我将它应用于实际数据,我必须从 fileB 添加 3 列作为 awk -F '\t' 'BEGIN { OFS = FS } NR == FNR { saved[$1] = $2FS$3FS4; next } { n = split($1, a, ","); sep = ""; field = ""; for(i = 1; i &lt;= n; ++i) { if(a[i] in saved) { field = field sep saved[a[i]]; sep = "," } } $1 = $1 OFS field }1' fileB fileA 然后在添加 awk -F "\t" "{print NF}" | sort | uniq 后计算总 cloumns 显示不相等的列。它仅添加在 fileB 中具有某些字符串的列,即忽略具有空字段的列,这会导致每行中的列数不相等。
    猜你喜欢
    • 2015-08-22
    • 2022-12-17
    • 2013-10-15
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    相关资源
    最近更新 更多