1

谁能解释一下正则表达式在 sed 替换命令中的工作原理。

$ cat path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/omni/lbin:/opt/omni/sbin:/root/bin

$ sed 's/\(\/[^:]*\).**/\1/g' path.txt
/usr/kbos/bin
/usr/local/sbin
/opt/omni/lbin

从上面的 sed 命令中,他们使用了反向引用和保存操作符的概念。谁能解释一下正则表达式,尤其是/[^:]*如何在替换命令中工作以仅获取每行中的第一条路径。

4

2 回答 2

5

我认为您在 sed 代码中写了一个额外的星号*,所以应该是这样的:

$ sed 's/\(\/[^:]*\).*/\1/g' file
/usr/kbos/bin
/usr/local/sbin
/opt/omni/lbin

更改分隔符将有助于更好地理解它:

sed 's#\(/[^:]*\).*#\1#g'

s#something#otherthing#g是一个基本sed命令,用于在整个文件中查找something和更改它。otherthing

如果你这样做了,s#(something)#\1#g那么你“保存”它something,然后你可以用\1.

因此,它正在做的是得到一个类似的模式/[^:]*,然后打印回来。/[^:]*意味着/ and then every char except :。所以它会得到/+ 所有的字符串,直到它找到一个分号:。它将存储那段字符串,然后将其打印回来。

小例子:

# get every char
$ echo "hello123bye" | sed 's#\([a-z]*\).*#\1#g'
hello

# get everything until it finds the number 3
$ echo "hello123bye" | sed 's#\([^3]*\).*#\1#g'
hello12
于 2013-08-06T09:32:47.143 回答
1
[^:]*

in regex 将匹配除 之外的所有字符:,因此它会匹配到:

/usr/kbos/bin

它也会匹配这些,

/usr/local/bin
/usr/jbin
/usr/bin
/usr/sas/bin

因为,这些都包含字符,而不是:

.*匹配任何字符,零次或多次。

因此,这个 regex[^:]*.*将匹配所有这些表达式:

/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/jbin:/usr/bin:/usr/sas/bin
/usr/bin:/usr/sas/bin

但是,您只能获得第一个字段(即,/usr/kbos/bin通过在 中使用反向引用sed),因为正则表达式输出找到的最长可能匹配项。

于 2013-08-06T09:36:02.000 回答