重复行2次,并从行到列进行转置

问题描述 投票:0回答:4

我想复制每一行2次并打印第5列和第6列的值。(每列的第5列和第6列的转置值)

我的意思是第6列(第二行)第5列(第一行)的值

输入文件

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

提前致谢

awk
4个回答
2
投票

要在这种情况下为N为2的最后N个字段中的每个字段重复打印行的开头:

$ 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
投票

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

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没有明确定义来触发在POSIX标准中重建$0print打印的整行记录)。上面的代码适用于GNU awk和mawk,但是使用BSD awk(在* BSD和Mac OS X上找到)它无法做任何事情。

因此,为了符合标准,我们必须更加明确,并强制要求从修改后的字段状态重建$0。这可以通过分配任何字段变量$1 ... $NF来完成,并且当在其他上下文中弹出此问题时使用$1=$1是常见的(例如:当只需要更改字段分隔符但不需要更改任何字段分隔符时数据):

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

我已经用GNU awk,mawk和BSD awk测试了这个(这些都是我可以放下的东西),我相信这将由the awk bit in POSIX覆盖,其中说“设置任何其他字段会导致重新评估$ 0“在顶部。请注意,规范可能在这一点上更明确,我有兴趣测试更多异国情调的awks是否表现相同。


1
投票

您可以尝试一下(考虑到您的Input_file始终与显示的相同,您需要每次打印前四个字段然后打印其余的字段(逐个打印以及前四个))。

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

1
投票

这可能适合你(GNU awk):

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

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

© www.soinside.com 2019 - 2024. All rights reserved.