0

我有一个字符串“r1/pkg/amd64/misc/hash/hash-r1.r5218.tbz”但是,我只想要“hash-r1.r5218.tbz”

所以,我试试这个

 unix$ a="r1/pkg/amd64/misc/hash/hash-r1.r5218.tbz"
 unix$ echo $a | sed 's/.*\/\([^\/]*\)\.tbz/\1/'  //[1]
 hash-r1.r5218   //I know this should work

 unix$ echo $a | sed 's/.*\/\([^\/]+\)\.tbz/\1/'  //[2]
 r1/pkg/amd64/misc/hash/hash-r1.r5218.tbz    //however I do not know why it does not work.

据我记得,正则表达式中的 + 意味着使用以前的正则表达式 1 次或更多次。* 在正则表达式中,表示使用前一个正则表达式 0 次或更多次。

谁能解释为什么 [2] 失败,非常感谢。

4

3 回答 3

2
a="r1/pkg/amd64/misc/hash/hash-r1.r5218.tbz"
echo $a | sed 's:.*/::; s:.tbz$::'
hash-r1.r5218

您不需要使用“/”作为模式/复制标记,您可以使用其他字符。':' 很受欢迎。

此外,当您知道目标数据两侧的确切文本时,您不必使用捕获缓冲区。

我已经替换了所有字符直到最后一个'/',依赖于.*所有字符和'/'来终止sed的标准贪婪搜索。你用注意分出尾随\.tbz

IHTH。

于 2012-11-01T18:52:23.793 回答
1

并非所有版本的正则表达式都sed支持+。有些确实支持它需要-r指定。但是为什么要使用sed代替basenameorecho ${a##*/}呢?

于 2012-11-01T21:39:21.330 回答
0

通过括号使用这个子匹配将抓取最后一个斜线到行尾的所有内容。

str="r1/pkg/amd64/misc/hash/hash-r1.r5218.tbz"
echo $str | sed -n -E -e 's/.+\/(.+)$/\1/p'

返回哈希-r1.r5218.tbz

哦,你的 #2 失败了,因为 sed 默认打印出匹配的每一行。使用 -n 标志会抑制这种情况,并且此正则表达式上的尾随 'p' 会打印出替换的替换部分。

于 2012-11-01T19:02:28.427 回答