sed 字符串子串
前面,我们已经简单学习了下 sed 中的 替换命令 s
。 见到本章节之前,我以为这个替换命令就是简简单单的。
可没想到 GNU sed 的 替换命令 功能强大,竟然支持 正则表达式分组和反向引用功能。
不过有点遗憾的是,这些功能只有 GNU sed 支持,苹果电脑自带的 sed
是万万支持不了的。
正则表达式分组和反向引用功能 允许我们在匹配的功能之外,捕获匹配到的字符串子串,然后再对这些子串进行处理。
纯文字描述有点拗口了,我们来看一个范例吧。
假设我们有一行文字
[www.twle.cn]$ echo "Three One Two"
其实就是使用 空格 隔开的简单的三个单词。
现在我们要这三个单词按行显示,也就是每个单词独占一行。
最简单的做法就是直接将 空格 替换为换行符。
[www.twle.cn]$ echo "Three One Two" | sed 's/ /\n/'
但结果并不是我们想要的
Three One Two
怎么办呢?
没有办法了吗?
不是的,我们可以使用 正则表达式分组和反向引用功能
echo "Three One Two" | sed 's|\(\w\+\) \(\w\+\) \(\w\+\)|\2\n\3\n\1|'
运行结果如下
One Two Three
哈哈,是不是看到了和之前不一样的 sed 替换正则表达式?
我们所熟悉的 /
变成了 竖线 |
了。
sed 中,竖线 |
也可以作为 模式 的分隔符。
sed 中的字符串子串使用 正则表达式分组功能和反向引用功能 来实现。
细细的说就是,sed 中的字符串子串使用 正则表达式分组功能 来对输入行进行正则匹配并分组,然后使用 正则表达式反向引用功能 来引用前面分组好的内容。
注意,sed 中的正则表达式分组功能中的 **小括号 ()
需要转义,也就是使用 \(
和 \)
。
-
\w
\w
是正则表达式的一个 元字符。\w
用于表示 ANSI 中的任何单个 数字、字母、下划线。也就是说,
\w
可以表示下面列出的任何单个字符0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+
-
+
+
在正则表达式中用于表示 一个或更多字符。 任何字符或字符串后面出现+
号,则表示这个字符或字符串需要最少出现一次。因此正则表达式
\(\w\+\)
用于表示可以匹配一个以上的任意字符(上面出现的任意字符) -
\n
对于
\n
,如果你非常熟悉正则表达式,那么它就不陌生了。\n
在正则表达式中被称为 正则表达式反向。其中n
是指第几个 圆括号()
所匹配的内容。比如说
One,Two,Three
和正则表达式\(\w\+\),\(\w\+\),\(\w\+\)
,\1
表示One
,\2
表示Two
,\3
表示Three
。echo "One,Two,Three" | sed 's|\(\w\+\),\(\w\+\),\(\w\+\)|\1\n\2\n\3|'
运行结果如下
One Two Three
你可能会问
\0
表示什么,它表示的是匹配的全部内容,也就是One,Two,Three
。echo "One,Two,Three" | sed 's|\(\w\+\),\(\w\+\),\(\w\+\)|\0\n\1\n\2\n\3|'
运行结果如下
One,Two,Three One Two Three
范例
下面的 sed 命令,我们使用 逗号(,
) 正则表达式分隔字符串,然后使用正则表达式反向引用 \n
将各个子串顺序调换一下
echo "Three,One,Two" | sed 's|\(\w\+\),\(\w\+\),\(\w\+\)|\2,\3,\1|'
运行以上 sed 命令,输出结果如下
One,Two,Three
注意
上面的范例,分隔符已经改成了 逗号(
,
),而不是之前的 **空格()。