用 sed 替换换行符(a la tr)

用 sed 替换换行符(a la tr)
echo "hi,my,name,is" | sed 's/,/\n/g' >out.txt

产量:

hi
my
name
is

但反过来说:

sed 's/\n/,/g' out.txt

产量:

hi
my
name
is

为什么不sed通过替换操作的反转来恢复操作?

答案1

尝试:

$ sed 'H;1h;$!d;x; s/\n/,/g' out.txt
hi,my,name,is

默认情况下,sed 一次只读入一行,对其进行处理并打印。由于单行永远不会有换行符,因此该命令s/\n/,/g不执行任何操作。如上所述,解决方案是立即读取整个文件,然后执行s/\n/,/g.

这些命令H;1h;$!d;x立即读取整个文件。最简单的做法可能是将此视为一个习语。如果你真的想知道血淋淋的细节:

  • H- 追加当前行以保留空间
  • 1h - 如果这是第一行,则用它覆盖保留空间
  • $!d- 如果这不是最后一行,则删除模式空间并跳转到下一行。
  • x - 交换保持和模式空间以将整个文件放入模式空间

替代方案:awk

$ awk 'NR>1{printf ","} {printf "%s",$0} END{print""}' out.txt
hi,my,name,is

或者:

$ awk '{printf "%s%s",(NR==1?"":","),$0} END{print""}' out.txt
hi,my,name,is

答案2

使用 gnu sed

echo "hi,my,name,is" | sed 's/,/\n/g' | sed -z 's/\n/,/g'

相关内容