我有一个包含以下模式的文件:
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
等等。在p
每出现5次之后,它必须转到新行,但是与标识符字段SUB一起。如果p
的出现小于5,则必须保持在同一行。
我尝试过:
awk -F'|' '{for(i=1;i<=NF;i++){printf("%s%s",$i,i%6?"|":"\n""|")}}'
它可以在6行后跳转到新行;但不能将SUB
保留在新行中。
答案 0 :(得分:2)
通过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
答案 1 :(得分:1)
以下是使用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], splice @F, 1, 5 while @F>1
:使用|
打印连接在一起的数组中的第一个字段和接下来的五个字段,同时减少数组(使用拼接)。我们继续这样做,直到我们的数组只包含其中的第一个元素。 答案 2 :(得分:1)
awk -F'|' '{for (i=2;i<=NF;i++) printf "%s%s",(i%5==2?(i>2?RS:"")$1:"")FS,$i; print ""}' file
答案 3 :(得分:0)
以下是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<=NF;i++) printf "%s|%s",(i%5==2?RS$1:""),$i} END {print ""}' file
SUB1|p1|p2|p3|p4|p5
SUB1|p6|p7
SUB2|p1|p2
SUB1|p1|p2|p3|p4|p5
SUB1|p6
如果启动时出现空白行是问题,请使用:
awk -F\| '{for (i=2;i<=NF;i++) printf "%s|%s",(i%5==2?(NR==1&&i==2?"":RS)$1:""),$i} END {print ""}' file
SUB1|p1|p2|p3|p4|p5
SUB1|p6|p7
SUB2|p1|p2
SUB1|p1|p2|p3|p4|p5
SUB1|p6