我的目录中有一堆文本文件,其中出现以下单词:
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(并删除-r
GNU 扩展)只需添加 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 上运行。