如何使用sed从第一行返回匹配并提前退出的东西?

时间:2009-11-20 23:54:35

标签: sed

我从

看到了

How to use sed to replace only the first occurrence in a file?

如何做我想要的大部分内容:

sed -n '0,/.*\(something\).*/s//\1/p'

这会找到某个东西的第一个匹配并提取它(当然我的真实例子更复杂)。我知道sed有一个'quit'命令可以让它提前停止,但我不知道如何将'q'与上面的行结合起来以获得我想要的行为。

我尝试用{p; q;}取代'p',就像我在一些例子中看到的那样,但这显然无效。

5 个答案:

答案 0 :(得分:9)

如果您还将替换命令放入块中(而不是仅放置打印并退出),“打印和退出”技巧仍然有效。

尝试:

sed -n '/.*\(something\).*/{s//\1/p;q}'

阅读如下:匹配斜杠之间给出的模式。如果找到此模式,请执行块中指定的操作:替换,打印和退出。通常,匹配和替换模式是相同的,但这不是必需的,因此's'命令也可以包含不同的RE。

实际上,这与ghostdog74为gawk回答的内容非常相似。

答案 1 :(得分:3)

我的具体用例是在git-p4导入的树上找到'git log',其中perforce分支用于最后一次提交。 git log(在没有-n的情况下调用时会记录每次发生的每次提交(对我来说都是数十万))。

我们无法知道a-priori为'-n'提供git的值。发布后,我发现我的解决方案是:

git log | sed -n '0,/.*\[git-p4:.*\/\/depot\/blah\/\([^\/]*\)\/.*/s//\1/p; /\[git-p4/ q' 

我仍然想知道如何使用非'/'分隔符执行此操作,而无需两次指定'git-p4'部分,一次用于提取,一次用于退出。必须有一种方法将两者结合在同一条线上......

答案 2 :(得分:1)

Sed通常可以选择指定多个要执行的模式(IIRC,它是-e选项)。这样,您可以指定在第一行之后退出的第二个模式。

另一种方法是使用sed提取第一行(sed '1q'),然后将其传递给第二个sed命令(上面显示的内容)。

答案 3 :(得分:1)

使用gawk

gawk '/MATCH/{
            print "do something with "$0
            exit 
}' file

答案 4 :(得分:0)

要“从第一行返回内容并退出”,您还可以使用 grep

grep --max-count 1 'something'

grep 应该比 sed 和 awk [1] 更快。即使没有,这种语法也更容易记住(并输入:grep -m1 'something')。

如果您不想看到整行,而只想看到匹配的部分,--only-matching (-o) 选项可能就足够了。