使用 AWK 更改两列的格式

使用 AWK 更改两列的格式

我有以下数据作为输入:

A 1,2
B 3,2,5
C 6,7
D 1,3,5,8

如何使用 AWK 获得以下输出?

A 1
A 2
B 3
B 2
B 5
C 6
C 7
D 1
D 3
D 5
D 8

答案1

$ awk -F '[ ,]' '{ for (i = 2; i <= NF; ++i) print $1, $i }' file
A 1
A 2
B 3
B 2
B 5
C 6
C 7
D 1
D 3
D 5
D 8

这将行视为由空格或逗号分隔的字段组成。对于每一行,awk程序都会迭代第二个字段,直到该行的末尾。对于每个字段,它输出第一的行上的字段与当前字段一起。

答案2

awk '{gsub(/,/,  "\n" $1 " "); print}' file

在此解决方案中,我们只是将每个“ ,”替换为"\n$1 "

答案3

使用sed启用的扩展正则表达式引擎,我们可以执行如下操作:

$ sed -re '
   s/^((\S+\s+)[^,]+),/\1\n\2/
   P;D
' file

我们Perl可以这样做:

$ perl -F'\s+|,' -lane '
   print join $", splice @F, 0, 2, $F[0] while @F > 1;
' file

按空格或逗号分割当前记录,并将其存储在零索引数组中@F

拼接数组的前两个元素并用单个空格将它们连接起来$"并打印它们。同时将两个删除的元素替换为第一个元素。重复此过程,直到只剩下一个元素。

答案4

如果sed是一个选项,你可以这样做:

sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/; ta' infile

考虑以下输入:

B 2,3,5,6
C 6,7
D 1,3,5,8
  1. ([^ ]* )捕获第一列(假设空格是分隔符);它将捕获B随后是一个空间)。
  2. (.*),捕获了直到最后一个逗号出现之前的所有内容;它将捕获2,3,5
  3. ([^,]*$)捕获了该行的其余部分(即:每次最后一个逗号之后的最后一个字段);它将捕获6

    • 因此\1\2\n\1\3第一行的第一次循环运行时的结果如下:

      sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/;q ;ta' infile 
      B 2,3,5
      B 6
      
    • 下一个循环运行结果如下:

      B 2,3
      B 5
      B 6
      
    • 下次运行...
    • 最后在最后一次循环运行中第一行将输出如下:

      sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/ ;ta ;q' infile
      B 2
      B 3
      B 5
      B 6
      
    • 现在阅读下一行并执行相同的过程,直到所有行都继续并完成。

相关内容