我有需要替换的带有空格(包括换行符)的文本。我想使用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
失败 为止和将变量设置为空字符串。