考虑特殊的正则表达式,如何正确使用 sed 替换命令的反向引用

Dav*_*d17 9 regex linux backreference sed regular-language

我正在学习 Linux 上的 sed s/regexp/replacement/ 命令。

phone.txt 中有一些号码

(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(777)555-1217
Run Code Online (Sandbox Code Playgroud)

我想使用正则表达式(我已经在https://www.freeformatter.com/regex-tester.html上测试过)

 (\(555\))(.*-)(.*$)
Run Code Online (Sandbox Code Playgroud)

匹配以 (555) 开头的数字。然后我希望这些匹配数字的这三个部分的输出为:(数字 (555)555-1212 的示例)

Area code: (555) Second: 555- Third: 1212
Run Code Online (Sandbox Code Playgroud)

我尝试了以下命令:

cat phone.txt | sed 's/\(\\\(555\\\)\)\(.*-\)\(.*$)/Area code: \1 Second: \2 Third: \3/'
Run Code Online (Sandbox Code Playgroud)

但系统给了我:

sed: -e expression #1, char 66: Unmatched ( or \(
Run Code Online (Sandbox Code Playgroud)

所有数字的通用命令是:

cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area code: \1 Second: \2 Third: \3/'
Run Code Online (Sandbox Code Playgroud)

来源: https: //www.tutorialspoint.com/unix/unix-regular-expressions.htm

但我只想对以 (555) 开头的数字执行 sed ,并通过后向引用将其添加到输出中。

你能告诉我如何正确地编写这个特殊命令吗?

Wik*_*żew 17

Ypu 在命令中使用 POSIX BRE 语法sed,在这种模式中,未转义的括号与文字括号匹配。转义括号定义了捕获组。

您可以使用

sed -E 's/(\(555\))(.*-)(.*)/Area code: \1 Second: \2 Third: \3/'
Run Code Online (Sandbox Code Playgroud)

查看在线演示

POSIX ERE 语法中的文字括号(通过-E选项启用)会像所有常见的在线正则表达式测试器一样进行转义,并且未转义的括号定义捕获组。


Dav*_*ica 5

您可以使用字符串中包含的格式进行概括,以选出第一个555、第二个555和第三个1212,而无需将自己限制在 的s/find/replace/替换形式中的任何特定前缀sed。然后,您可以根据需要通过在替换之前包含匹配条件来进行限制,您可以在其中输入555or666等​​...

要包含模式匹配和替换,请使用以下形式:

sed '/pattern/s/find/replace/'
Run Code Online (Sandbox Code Playgroud)

要使模式匹配抑制除与模式匹配的行之外的所有行的输出,您可以传递选项-n来抑制模式空间的打印,并p在替代形式的末尾包含 a 以显式打印那些匹配的行,例如

sed -n '/pattern/s/find/replace/p'
Run Code Online (Sandbox Code Playgroud)

现在,让我们转向您手头的问题。要将重新格式化的输出限制为仅以(555)您开头的行,请执行以下操作:

$ sed -n '/^(555)/s/^(\([^)]*\))\([^-]*\)-\(.*\)$/Area code: (\1) Second: \2- Third: \3/p' file
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
Run Code Online (Sandbox Code Playgroud)

注意:反向引用仅捕获数字,而不捕获(..)or '-'

要重新格式化所有行,您可以删除 and-n以及/pattern/最后的p,仅使用基本sed 's/find/replace/形式,例如

$ sed 's/^(\([^)]*\))\([^-]*\)-\(.*\)$/Area code: (\1) Second: \2- Third: \3/' file
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
Area code: (666) Second: 555- Third: 1215
Area code: (777) Second: 555- Third: 1217
Run Code Online (Sandbox Code Playgroud)

检查一下,如果您还有其他问题,请告诉我。