【问题标题】:Why is translate working and not sed for line feed为什么翻译工作而不是 sed 换行
【发布时间】:2019-12-25 09:57:48
【问题描述】:

我想用 # 之类的东西替换换行符

我已经尝试过 sed 但 \n 不起作用,并且 \x0a 也是如此

我得到了文件 z1

cat z1|hd

00000000  30 0a 61 0a 0a 31 0a 62  0a 0a 32 0a 63 0a        |0.a..1.b..2.c.|

如果我尝试

cat z1|sed $'s/\x30//g' 

一切正常

但是对于sed中的换行不起作用,只是一个错误信息

cat z1|sed $'s/\x0a//g' 

如果我尝试

cat z1| tr "\n" "#"|hd

换行一切正常

为什么 sed 不能用于换行?

【问题讨论】:

  • 因为默认情况下,sed 使用 LF 字符将文本分割成行。

标签: string bash sed replace tr


【解决方案1】:

sed 将不匹配文字换行符,因为sed 中的命令由换行符分隔。所以sed,在解析命令时,看到一个换行符并假设它是这个命令的结尾。然后sed 出现语法错误,因为s/ 是无效命令,s 需要三个分隔符,这里是/。更具体地说,posix sed documentation 明确禁止在 BRE 中嵌入文字换行符 s/BRE/replacement/flags 命令:A literal <newline> shall not be used in the BRE of a context address or in the substitute function

除此之外,sed 逐行解析输入,但忽略输入中的换行符并在打印时自动附加换行符。所以即使你做了s/\n/#/ 它也不会做任何事情,因为输入中没有换行符。您可以:将所有行追加到保持空间,然后用模式空间切换保持空间,然后替换换行符。这是@potong 提出的解决方案。

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed '1h;1!H;$!d;x;y/\n/#/' file
    

    这会将文件读入内存,然后将 \n's 转换为 #'s

    替代方案:

    sed -z 'y/\n/#/' file
    

    【讨论】:

    • 不,第一个命令应该适用于所有与 posix 兼容的seds。第二个仅适用于 GNU sed - 它支持 -z 选项。
    【解决方案3】:

    有接受\n 或十六进制字符代码的sed 版本,但这不是可移植的。如果你不能使用tr(为什么不呢?)那么也许可以探索一下 Perl,这当然不是标准的,但几乎无处不在;并且因为只有一种实现,所以它可以在 Perl 可用的任何地方工作。

    perl -pe 'y/\n/#/' z1
    

    还要注意没有useless cat.

    【讨论】:

    • "Perl is not standard" 你的意思是它没有得到管理标准机构的批准吗?
    • 是的,sed 在 POSIX 等中是标准化的,而 Perl 不是。具有讽刺意味的是,该标准并未针对此特定用例指定特定行为。
    猜你喜欢
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2018-04-15
    • 2013-07-01
    相关资源
    最近更新 更多