将每5条记录的单行转换为多行,但使用awk保留第一个字段

将每5条记录的单行转换为多行,但使用awk保留第一个字段,awk,Awk,我有一个具有以下模式的文件: SUB1|p1|p2|p3|p4|p5|p6|p7 SUB2|p1|p2 现在,所需的输出是: SUB1|p1|p2|p3|p4|p5 SUB1|p6|p7 SUB2|p1|p2 规则是第一个字段(SUB1,SUB2等等)是其余字段(p1,p2,p3,p4,p5等等)的标识符。每出现5次p后,它必须转到新行,但与标识符字段SUB一起。如果p的出现次数少于5次,它必须保持在同一行 我试过: awk -F'|' '{for(i=1;i<=NF;i+

我有一个具有以下模式的文件:

SUB1|p1|p2|p3|p4|p5|p6|p7 
SUB2|p1|p2
现在,所需的输出是:

SUB1|p1|p2|p3|p4|p5  
SUB1|p6|p7  
SUB2|p1|p2

规则是第一个字段(
SUB1
SUB2
等等)是其余字段(
p1
p2
p3
p4
p5
等等)的标识符。每出现5次
p
后,它必须转到新行,但与标识符字段SUB一起。如果
p
的出现次数少于5次,它必须保持在同一行

我试过:

awk -F'|' '{for(i=1;i<=NF;i++){printf("%s%s",$i,i%6?"|":"\n""|")}}'
awk-F'|'''{for(i=1;i通过GNU-sed

$ sed -r 's/^([^|]*)(\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*)\|(.*)$/\1\2\n\1|\3/g' file
SUB1|p1|p2|p3|p4|p5
SUB1|p6|p7 
SUB2|p1|p2
示例:

$ cat file
SUB1|p1|p2|p3|p4|p5|p6|p7 
SUB2|p1|p2
SUB1|p1|p2|p3|p4|p5|p6
$ sed -r 's/^([^|]*)(\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*)\|(.*)$/\1\2\n\1|\3/g' file
SUB1|p1|p2|p3|p4|p5
SUB1|p6|p7 
SUB2|p1|p2
SUB1|p1|p2|p3|p4|p5
SUB1|p6
通过GNU sed

$ sed -r 's/^([^|]*)(\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*)\|(.*)$/\1\2\n\1|\3/g' file
SUB1|p1|p2|p3|p4|p5
SUB1|p6|p7 
SUB2|p1|p2
示例:

$ cat file
SUB1|p1|p2|p3|p4|p5|p6|p7 
SUB2|p1|p2
SUB1|p1|p2|p3|p4|p5|p6
$ sed -r 's/^([^|]*)(\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|[^|]*)\|(.*)$/\1\2\n\1|\3/g' file
SUB1|p1|p2|p3|p4|p5
SUB1|p6|p7 
SUB2|p1|p2
SUB1|p1|p2|p3|p4|p5
SUB1|p6

这是一个
awk
版本:

cat file
SUB1|p1|p2|p3|p4|p5|p6|p7
SUB2|p1|p2
SUB1|p1|p2|p3|p4|p5|p6

awk-F\|{for(i=2;i这里是一个
awk
版本:

cat file
SUB1|p1|p2|p3|p4|p5|p6|p7
SUB2|p1|p2
SUB1|p1|p2|p3|p4|p5|p6

awk-F\|'{for(i=2;i这里有一个使用
perl
的替代解决方案:

$ perl -F'\|' -lane 'print join "|", $F[0], splice @F, 1, 5 while @F>1' file
SUB1|p1|p2|p3|p4|p5
SUB1|p6|p7|p8|p9|p10
SUB1|p11
SUB2|p1|p2|p3|p4|p5
SUB2|p6
SUB1|p1|p2|p3|p4|p5
SUB1|p6|p7
说明:
  • -F'\\\'
    :将输入字段分隔符设置为
  • -l
    :在打印过程中选择换行符并将其放回原处
  • -a
    :基于输入字段分隔符填充数组
    @F
  • -n
    :创建一个
    while(){..}
    循环来处理每一行
  • -e
    :执行它后面的代码块
  • print join“|”、$F[0],在@F>1时拼接@F、1、5
    :从与
    |
    连接在一起的数组中打印第一个字段和接下来的五个字段,同时缩小数组(使用拼接)。我们继续这样做,直到数组中只剩下第一个元素

    • 这里有一个使用
      perl的替代解决方案:

      $ perl -F'\|' -lane 'print join "|", $F[0], splice @F, 1, 5 while @F>1' file
      SUB1|p1|p2|p3|p4|p5
      SUB1|p6|p7|p8|p9|p10
      SUB1|p11
      SUB2|p1|p2|p3|p4|p5
      SUB2|p6
      SUB1|p1|p2|p3|p4|p5
      SUB1|p6|p7
      
      说明:
      • -F'\\\'
        :将输入字段分隔符设置为
      • -l
        :在打印过程中选择换行符并将其放回原处
      • -a
        :基于输入字段分隔符填充数组
        @F
      • -n
        :创建一个
        while(){..}
        循环来处理每一行
      • -e
        :执行它后面的代码块
      • print join“|”、$F[0],在@F>1时拼接@F、1、5
        :从与
        |
        连接在一起的数组中打印第一个字段和接下来的五个字段,同时缩小数组(使用拼接)。我们继续这样做,直到数组中只剩下第一个元素
      awk-F'|''''{for(i=2;i2?RS:)$1:“”)FS,$i;print'}文件
      
      awk-F'|'''{for(i=2;i2?RS:)$1:“”)FS,$i;print'}文件
      

      为什么
      SUB2 | x1 | x2
      更改为
      SUB2 | p1 | p2
      ?@AvinashRaj。很抱歉,在构建问题时出错。我现在已将其正确编辑。请尝试
      awk-F“|”{(i=1;i如果“p”在两行或多行中出现五次以上,会发生什么情况?您想要第一个SUB还是第二个SUB?实际情况是:SUB1(订户)几乎没有产品(P1、P2、P3、P4、P5、P6、P7)。此外,SUB2、SUB3任何数量的订户也可以有相同的产品;这就是为什么我必须提到“SUB”是一个标识符。为什么
      SUB2 | x1 | x2
      更改为
      SUB2 | p1 | p2
      ?@AvinashRaj。很抱歉,在构建问题时出错。我现在已正确编辑了它。请尝试
      awk-F“|”{(i=1;i如果“p”在两行或多行中出现五次以上,会发生什么情况?您想要第一个SUB还是第二个SUB?实际情况是:SUB1(订户)几乎没有产品(P1、P2、P3、P4、P5、P6、P7)。此外,SUB2、SUB3任何数量的订户也可以有相同的产品;这就是为什么我必须提到“SUB”是一个识别器。非常感谢!!!它像一个冠军一样工作。我们有什么办法可以用awk来解决吗?@Unihedron我同意你应该总是接受一个答案,如果有一个好的答案。但是你应该总是等一个小时,有人可能会发布一个更好的答案。@Jotne这是一个自动评论。除此之外,我同意你的立场。你可能bly需要一个
      sed
      中的循环。如果有更多的数据是5的倍数,则该循环将不起作用。这可以缩短一点:
      gsed-r的/^([^ |]*)(\\|[^ |]*){5}/&\n\1/'file
      非常感谢!!!它像一个冠军一样工作。我们有什么办法可以用awk来解决吗?@Unihedron我同意如果有一个好的答案,你应该总是接受。但是你应该总是等上一个小时,有人可能会发布一个更好的答案。@Jotne这是一个自动评论。除此之外,我同意你的立场。你有问题吗如果有更多的数据是5的倍数,那么在
      sed
      中需要一个循环就不起作用了。这可以缩短一点:
      gsed-r的/^([^ |]*)(\\\\\[^ |]*{5}/&\n\1/'文件
      @AvinashRaj我只是想发布一个修复程序。@AvinashRaj我只是想发布一个修复程序。