用 sed 插入换行符?

用 sed 插入换行符?

我的目录中有一堆文本文件,其中出现以下单词:

GSM89103AATF

实际上,数字可以改变,所以另一个例子可以是GSM89089AATF。我需要将这些事件替换为GSM89089\nAATF,即插入新行。我可以用 来做这个sed吗?

答案1

你可以使用 GNU sed

 $ sed -r 's/(GSM[0-9]{5})(AATF)/\1\n\2/' file.in >file.out

该模式匹配两个单独捕获组中的第一部分,然后匹配第二部分。我假设第一部分后面总是跟着GSM五位数字。替换只是粘贴从两个组捕获的数据,中间换行。

-r是需要的,因为我使用了扩展的正则表达式。某些实现sed使用-E代替-r这些类型的正则表达式。

在没有 GNU 的系统上sed

$ sed 's/\(GSM[0-9]\{5\}\)\(AATF\)/\1\
> \2' file.in >file.out

也就是说,使用 BRE 而不是 ERE(并删除-rGNU 扩展)只需添加 a\并在 后面按回车键\1,然后在下一行继续替换模式。 >是一个提示,而不是您键入的内容。

答案2

这适用于我的 Mac 和各种 Linux 发行版:

#!/usr/bin/env bash

PATTERN="(GSM[0-9]{5})(AATF)"

sed -E -e $"s_${PATTERN}_\1\\
\2_g" < file_with_values

在哪里:

  • PATTERN:您可以在变量中定义模式,使替换表达式更易于阅读
  • sed -E -e:设置sed为使用扩展正则表达式 (-E) 并使用提供的脚本 (-e)
  • $"...": 用于翻译字符串,并允许变量。看看这里:bash 引用。它可能并不在所有情况下都是安全的,但就您而言应该没问题
  • s_ ..._...\2_g: 是替换字符串;我使用_作为分隔符,这样您就不需要转义/,并且考虑到您需要捕获组(\1\2),它只会使字符串更易于阅读。请注意\\后面的新行。$"..."允许使用新行

如果不需要变量,可以使用$'....'带有单引号的美元符号。在这种情况下,您可以使用\n但不能插入新行

使用$"..."似乎相当可移植:我的代码具有类似的实现,可以在 docker alpine、centos、debian、fedora、ubuntu 上运行。

相关内容