任何人都可以解释一下正则表达式在sed substitute命令中是如何工作的。
$ 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命令中,他们使用了返回引用和保存运算符的概念。 任何人都可以解释一下正则表达式,特别是 / [^:] * 如何在substitute命令中工作,只获得每一行中的第一条路径。
答案 0 :(得分: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
答案 1 :(得分:1)
[^:]*
正则表达式中的将匹配除:
之外的所有字符,因此它将匹配到此为止:
/usr/kbos/bin
也会匹配这些,
/usr/local/bin
/usr/jbin
/usr/bin
/usr/sas/bin
因为,这些都包含不是:
.*
匹配任何字符,零次或多次。
因此,这个正则表达式[^:]*.*
将匹配所有这些表达式:
/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
),因为正则表达式输出找到的最长匹配项。