复制行2次并从行到列转置

时间:2018-09-08 05:28:49

标签: awk

我想每行重复2次,并分别打印第5列和第6列的值(第5列和第6列的值从列到行的转置)

我在第5列(第一行)的平均值在第6列(第二行)的值

输入文件

08,1218864123180000,3201338573,VV,22,27
08,1218864264864000,3243738789,VV,15,23
08,1218864278580000,3244738513,VV,3,13
08,1218864310380000,3243938789,VV,15,23
08,1218864324180000,3244538513,VV,3,13
08,1218864334380000,3200538561,VV,22,27

所需的输出

08,1218864123180000,3201338573,VV,22
08,1218864123180000,3201338573,VV,27
08,1218864264864000,3243738789,VV,15
08,1218864264864000,3243738789,VV,23
08,1218864278580000,3244738513,VV,3
08,1218864278580000,3244738513,VV,13
08,1218864310380000,3243938789,VV,15
08,1218864310380000,3243938789,VV,23
08,1218864324180000,3244538513,VV,3
08,1218864324180000,3244538513,VV,13
08,1218864334380000,3200538561,VV,22
08,1218864334380000,3200538561,VV,27

我使用此代码将行重复2次,但我无法通过第5列和第6列的值来确定条件

awk '{print;print}' file

预先感谢

4 个答案:

答案 0 :(得分:2)

在这种简单的情况下,必须删除最后一个字段并将其放在最后一行,您可以这样做

awk -F , -v OFS=, '{ x = $6; NF = 5; print; $5 = x; print }'

此处-F ,-v OFS=,分别将输入和输出字段分隔符设置为逗号,而代码确实如此

{
  x = $6    # remember sixth field
  NF = 5    # Set field number to 5, so the last one won't be printed
  print     # print those first five fields
  $5 = x    # replace value of fifth field with remembered value of sixth
  print     # print modified line
}

这种方法可以扩展为使用this question接受答案中的函数来处理中间的字段。

编辑:如Ed在注释中所述,未明确定义写入NF来触发$0的重建({{1 }}打印)。上面的代码可用于GNU awk和mawk,但可用于BSD awk(在* BSD以及可能在Mac OS X上找到)。

因此,要符合标准,我们必须更加明确,并迫使awk从修改后的字段状态重建print。可以通过将任何字段变量分配给$0 ... $1来完成,通常会在其他情况下出现此问题时使用$NF(例如:仅当字段分隔符需要更改,但不需要更改任何数据):

$1=$1

我已经用GNU awk,mawk和BSD awk(它们都是我可以使用的awk)进行了测试,并且我相信the awk bit in POSIX会对此进行说明,其中表示“设置其他任何字段会导致在顶部重新评估$ 0“。请注意,规格在这一点上可能更加明确,我想测试一下更多奇特的awks是否具有相同的行为。

答案 1 :(得分:2)

要为最后N个字段重复打印一行的开始,在这种情况下,N为2:

$ awk -v n=2 '
    BEGIN { FS=OFS="," }
    {
        base = $0
        sub("("FS"[^"FS"]+){"n"}$","",base)
        for (i=NF-n+1; i<=NF; i++) {
            print base, $i
        }
    }
' file
08,1218864123180000,3201338573,VV,22
08,1218864123180000,3201338573,VV,27
08,1218864264864000,3243738789,VV,15
08,1218864264864000,3243738789,VV,23
08,1218864278580000,3244738513,VV,3
08,1218864278580000,3244738513,VV,13
08,1218864310380000,3243938789,VV,15
08,1218864310380000,3243938789,VV,23
08,1218864324180000,3244538513,VV,3
08,1218864324180000,3244538513,VV,13
08,1218864334380000,3200538561,VV,22
08,1218864334380000,3200538561,VV,27

答案 2 :(得分:1)

请尝试以下操作(考虑到您的Input_file始终与所示的相同,并且您需要每次打印第四个字段,然后打印其余字段(与第四个字段一一打印)。

awk 'BEGIN{FS=OFS=","}{for(i=5;i<=NF;i++){print $1,$2,$3,$4,$i}}'  Input_file

答案 3 :(得分:1)

这可能对您有用(GNU awk):

awk '{print gensub(/((.*,).*),/,"\\1\n\\2",1)}' file

用换行符替换最后一个逗号,而前几个字段则倒数第二个。