Sed替换不做我想做的事情并认为它应该做

时间:2010-04-01 16:26:03

标签: regex sed

我正在尝试使用sed来获取在文件路径中编码的一些信息,这些信息作为参数传递给我的脚本(Bourne sh,如果重要的话)。 从这个示例路径,我希望结果为8

PATH=/foo/bar/baz/1-1.8/sing/song

我首先使用sed作为grep:

来关闭正则表达式
echo $PATH | sed -n -e  "/^.*\/1-1\.\([0-9][0-9]*\).*/p"

这正确识别了字符串,因此我对其进行了编辑以对其进行替换:

echo $PATH | sed -n -e "s/^.*\/1-1\.\([0-9][0-9]*\).*/\1/"

但这不会产生任何输出。我知道我只是没有看到一些简单的东西,但我真的很欣赏任何有关我做错的想法或其他调试sed正则表达式的方法。

(编辑)

在示例路径中,除数字组件之外的组件可以包含与我列出的数字路径组件类似的数字,但不完全相同。我正在尝试完全匹配1-1的组件。并看看有多少是什么。

也可以使用正则表达式不匹配的输入字符串,并且不应该产生输出。

5 个答案:

答案 0 :(得分:2)

要发送的-n选项会抑制正常输出,并且由于您的第二行没有p命令,因此不会输出任何内容。摆脱-n或坚持p回到最后

答案 1 :(得分:1)

看起来你正试图从8获取1-1.8(其中8是任何数字序列),是吗?如果是这样,我会使用:

echo /foo/bar/baz/1-1.8/sing/song | sed -e  "s/.*\/1-1\.//" -e "s/[^0-9].*//"

毫无疑问,你可以使用一个sed“指令”(-e)来处理它,但有时候只是将其分解就更容易了。

第一个从开始到包括1-1.删除所有内容,第二个条带从第一个非数字开始到结束。

$ echo /foo/bar/baz/1-1.8/sing/song | sed -e  "s/.*\/1-1\.//" -e "s/[^0-9].*//"
8
$ echo /foo/bar/baz/1-1.752/sing/song | sed -e  "s/.*\/1-1\.//" -e "s/[^0-9].*//"
752

而且,顺便说一句,这实际上是如何我调试sed正则表达式。我把简单的指令放在独立的指令中(或者用于其他过滤命令的管道的独立部分),这样我就可以看到每个指令的作用。


编辑后,这也有效:

$ echo /foo/bar/baz/1-1.962/sing/song | sed -e  "s/.*\/1-1\.\([0-9][0-9]*\).*/\1/"
962

关于你的评论:

  

在示例路径中,除数字组件之外的组件可以包含与我列出的数字路径组件类似的数字,但不完全相同。我正在尝试完全匹配1-1的组件。并看看有多少是什么。

我给你的两部分sed命令应该在字符串中的任何地方使用数字(只要在你感兴趣的之后没有1-1. )。那是因为它实际上删除了特定的1-1.字符串,然后从第一个非数字字符串中删除。如果您有一些按预期工作的示例,请将它们作为更新投入问题,我将调整答案。

答案 2 :(得分:1)

您可以使用+(一个或多个)代替*(零或更多)来缩短命令:

sed -n -e "s/^.*\/1-1\.\([0-9]\+\).*/\1/"

答案 3 :(得分:1)

不要使用PATH作为变量。它与PATH环境变量

发生冲突
echo $path|sed -e's/.*1-1\.//;s/\/.*//'

答案 4 :(得分:0)

你不需要用/(s / a / b / g)来划分你的模式,但可以选择每个角色,所以如果你正在处理路径,#比/更有用:

echo /foo/1-1.962/sing | sed -e  "s#.*/1-1\.\([0-9]\+\).*#\1#"