如何用 sed 替换换行符?

如何用 sed 替换换行符?

我有需要替换的带有空格(包括换行符)的文本。我想使用sed,但 AIX 似乎不支持答案我发现的sed换行问题。我使用的 bash 版本是“GNU bash,版本 3.00.16(1)-release (powerpc-ibm-aix5.1)”

如果我运行一个输出一堆文本行的命令,例如:

alias:  aliasname
                10:00:00:00:00:00:00:00

使其每行一行的最佳方法是什么?如果我使用ssh user@system command | tr '\n' ' ',它会替换两个换行符,并且我需要保留最后一个换行符,否则输出会变成一行。

编辑:到目前为止我尝试过的是:

  • | sed -e ':1' -e 'N' -e '$!b1' -e 's/\n/ /g'它替换所有换行符,将整个输出流放入一行中。
  • | while read i; do printf "%s " $i; done; echo这也替换了所有换行符
  • | tr -d '\n'| tr -d '\n'; echo,仍然替换所有换行符,但是 echo 在最后一个命令处添加了一个。

答案1

最简单

ssh user@system command | tr '\n' ' ';echo

或者如果你想要sed

ssh user@system command | sed 'N;s/\n\s\+/ /'

答案2

这是一个纯粹的 bash 方法,它将删除每对中的第一个换行符:

command | 
  while IFS=$'\n' read i; do 
    let c++; [ "$(expr $c % 2)" -eq "0" ] && echo "$i" || printf "%s " "$i"; 
  done

如果您不需要保持空格不变,则可以省略IFS

command | 
  while read i; do 
    let c++; [ "$(expr $c % 2)" -eq "0" ] && echo "$i" || printf "%s " "$i"; 
  done

同样的想法使用perl

command | perl -ne 'chomp;$. % 2 == 0 ? print "$_\n" : print "$_"' 

答案3

尝试这个:

sed -e ':1' -e 'N' -e '$!b1' -e 's/\n/ /g'

答案4

最好用 ; 来做到这一点sed。看为什么使用 shell 循环处理文本被认为是不好的做法?  例如,这个微小的变化科斯塔斯的第二个sed答案 ( ):

sed 'N; s/\n/ /'

很好地回答了这个问题: N将下一行输入附加到模式空间中,然后s/\n/ /进行替换。 (然后每两行输入重复这些命令。)

但是,如果您想完全在 shell 中完成此操作,则这种变体特登的回答:

while IFS= read -r line1
do
    IFS= read -r line2; printf '%s %s\n' "$line1" "$line2"
done

无需运行任何外部程序即可工作。逻辑很(恕我直言)简单:虽然不在输入末尾,但读取一行,然后读取另一行,然后在一行上输出用空格分隔的两个字符串。

上面的代码有一个边缘情况的问题:如果输入是偶数个格式良好的行,后跟一些不以换行符结尾的字符,则它会丢弃最后(部分)行。 (特登的回答有同样的问题,但不仅仅是偶数行。)这是因为read当它读取部分行时返回失败,即使它确实将数据放入变量中。所以修复方法是这样的:

while IFS= read -r line1  ||  [ "$line1" != "" ]
do
    IFS= read -r line2; printf '%s %s\n' "$line1" "$line2"
done

一直持续到read失败 为止将变量设置为空字符串。

相关内容