解释

解释

我想要转换:

A,p
B,q
C,r
D,s

进入:

A,p,q
B,q,r
C,r,s

使用sed

答案1

我怀疑sed这不是什么问题(其他人可能知道如何用 做得更好sed),但情况如下:

$ sed '2,$ s/.$/&,&/' file | sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta' | sed '$d'
A,p,q
B,q,r
C,r,s

笔记

sed '2,$ s/.$/&,&/'表示复制除第一行之外的所有行的最后一个字符,并添加逗号:

  • 2,$从第二行开始
  • s/old/new/old用。。。来代替new
  • .$最后一个字符
  • &匹配的模式

sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta;'意思是取出第一行之后每一行的最后一个字符,并将其粘贴到上一行的末尾:

  • -r使用 ERE
  • :a标签:从这里执行
  • ;分隔命令
  • N将下一行读入模式空间,以便我们可以用它\n来表示模式中的换行符
  • (.)保存一个字符以供以后使用
  • ?零个或一个前一个字符
  • $行结束
  • \1参考已保存的模式
  • ta如果最后一条s命令成功,则分支:a并再次执行循环
  • $d删除最后一行

如果您的文件的逗号之间不只有单个字符,您将无法使用上面非常简单的正则表达式。如果文件以逗号分隔,则这是一个有效的版本。例如,给定

January,apple
February,pear
March,kiwi
April,mango

你可以这样做,如果有的话,这也有效当然只有一个字符

$ sed '2,$ s/[^,]*$/&,&/' file | sed -r ':a;N;s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/;ta;' | sed '$d'
January,apple,pear
February,pear,kiwi
March,kiwi,mango

sed;脚本可以写在多行上。我不能说这显著提高了可读性;)但它可能更具可移植性,因为在非 GNU 版本的使用上有限制sed

sed '2,$ s/[^,]*$/&,&/' file |
sed -r '{:a
          N
          s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/
          ta}' |
sed '$d'

[^,]*表示零个或多个不是逗号的字符。

答案2

我认为这是一种在单个 sed 调用中完成此操作的方法:

sed -nE '$!{:a;N;s/(.*)\n(.*)(,[^,]*$)/\1\3\n\2\3/;P;D;ba;}' file
A,p,q
B,q,r
C,r,s

解释

:a;N;...P;D;ba结构本质上维护一个双行缓冲区,我们可以在其中拆分字段并复制/移动字符组:

$!{                                   # For any line except the last
  :a                                  # Enter a loop:
  N                                   # Append the following line, after a newline  
  s/(.*)\n(.*)(,[^,]*)$/\1\3\n\2\3/   # Capture (1) up to the newline, 
                                      # (2) from the newline to the last comma, 
                                      # and (3) everything else into groups and 
                                      # copy group 3 before the newline
  P                                   # Print everything up to the newline
  D                                   # Delete everything up to the newline, 
                                      # ready for the next iteration
  ba
}

请注意,使用-E(或-r)扩展正则表达式不是必需的 - 它只是减少所需的转义量。

相关内容