在AWK中,如何拆分与"记录"具有相同字符串的连续行?

Jus*_*ner 3 string awk text sed

假设我有下面的文字.

aaaaaaa
aaaaaaa
bbb
bbb
bbb
ccccccccccccc
ddddd
ddddd
Run Code Online (Sandbox Code Playgroud)

有没有办法修改文本如下.

1 aaaaaaa
1 aaaaaaa
2 bbb
2 bbb
2 bbb
3 ccccccccccccc
4 ddddd
4 ddddd
Run Code Online (Sandbox Code Playgroud)

Tom*_*ech 11

你可以在awk中使用这样的东西:

$ awk '{print ($0!=p?++i:i),$0;p=$0}' file
1 aaaaaaa
1 aaaaaaa
2 bbb
2 bbb
2 bbb
3 ccccccccccccc
4 ddddd
4 ddddd
Run Code Online (Sandbox Code Playgroud)

i只要当前行与前一行不同,就会递增.p保持前一行的值,$0.

或者,正如JID所建议的那样:

awk '$0!=p{p=$0;i++}{print i,$0}' file
Run Code Online (Sandbox Code Playgroud)

当前行不同时p,替换p并递增i.请参阅评论以讨论任何一种方法的优缺点:)

NeronLeVelu的进一步贡献(甚至更短!)

$ awk '{print i+=($0!=p),p=$0}' file
Run Code Online (Sandbox Code Playgroud)

此版本在print语句中执行添加分配和基本分配.这是有效的,因为每个赋值的返回值是已分配的值.


正如评论中所指出的,如果文件的第一行为空,则行为会略有变化.假设第一行应始终以a开头1,则可以将以下块添加到任何一行的开头:

NR==1{p=$0;i=1}
Run Code Online (Sandbox Code Playgroud)

即在第一行上,初始化p到线(空或不)和内容物i1.感谢Wintermute提出这个建议.

  • 如果$ 0为空或零,则@JID将无法递增x. (2认同)
  • @JID那个有效(并且像往常一样削减几个角色:). (2认同)
  • 是的,这是有效的,但我个人更喜欢三元运算解决方案.nbd,但是当在当前记录上运行的代码之后设置`prev` var并且我知道它的效率较低时我发现它最清楚但是我也更喜欢为每个记录设置它,因为每次我看到它有条件地设置我有考虑条件是否正确,我试图避免我必须考虑的代码:-). (2认同)
  • 只是为了好玩`awk'{print i + =($ 0!= p),$ 0; p = $ 0}'`还可以使用`awk'{print i + =($ 0!= p),p = $ 0}'`我的系统但不确定无处不在 (2认同)