我从
看到了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',就像我在一些例子中看到的那样,但这显然无效。
答案 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
) 选项可能就足够了。