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

如何使用sed从第一行返回匹配的内容并提前退出?,sed,Sed,我从 如何做我想做的大部分事情: sed -n '0,/.*\(something\).*/s//\1/p' 这会找到某些内容的第一个匹配项并将其提取出来(当然,我的真实示例更复杂)。我知道sed有一个'quit'命令,可以让它提前停止,但我不知道如何将'q'与上面的行结合起来,以获得我想要的行为 正如我在一些示例中看到的,我尝试用{p;q;}替换'p',但这显然不起作用。Sed通常有一个选项来指定要执行的多个模式(IIRC,它是-e选项)。这样,您可以指定在第一行之后退出的第二个模式 另一

我从

如何做我想做的大部分事情:

sed -n '0,/.*\(something\).*/s//\1/p'
这会找到某些内容的第一个匹配项并将其提取出来(当然,我的真实示例更复杂)。我知道sed有一个'quit'命令,可以让它提前停止,但我不知道如何将'q'与上面的行结合起来,以获得我想要的行为


正如我在一些示例中看到的,我尝试用{p;q;}替换'p',但这显然不起作用。

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

另一种方法是使用
sed
提取第一行(
sed'1q'
),然后将其传输到第二个
sed
命令(如上所示)。

使用gawk

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

我的特定用例是通过git-p4导入树上的“git日志”来确定上次提交使用了哪个Performce分支。git log(在没有-n的情况下调用时,将记录每次发生的提交(对于我来说是几十万次))

我们无法预先知道为'-n'赋予git什么值。发布此消息后,我找到了我的解决方案,它是:

git log | sed -n '0,/.*\[git-p4:.*\/\/depot\/blah\/\([^\/]*\)\/.*/s//\1/p; /\[git-p4/ q' 
我仍然想知道如何使用非“/”分隔符来实现这一点,而不必两次指定“git-p4”部分,一次用于提取,一次用于退出。必须有一种方法将两者合并到同一行中…

如果您还将替换命令放入块中(“打印并退出”)的话,“打印并退出”技巧会起作用

尝试:

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

实际上,这与gawk的回答非常相似。

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

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


如果您不想看到整行内容,而只想看到匹配的部分,那么
--仅匹配
-o
)选项可能就足够了。

您能展示更多您得到的内容、您想要的内容以及它们之间的区别吗?我做了
echo-e“aaa111aaa\nbbb111bbb”| sed-n'0、/.\(111\).*/s//\1/p'
得到了一个“111”。然后我做了
echo-e“aaa 111 aaa\nbbb 111 bbb”| sed-n'0、/\(.*\(111\).\)/s//\1/p'
来显示完整的行,以确保它得到了什么,并输出了我所期望的“aaa 111 aaa”。请注意,我没有使用
q
。你的方法会生成正确的输出,但它会继续处理整个文件,即使没有更多的工作要做,这对于大型文件或在管道中使用时是非常糟糕的。我的特定用例是通过git-p4导入树上的“git日志”来确定上次提交使用了哪个Performce分支。git log(在没有-n的情况下调用时,将记录每次发生的提交(对我来说是数十万次)。我们无法事先知道git for'-n'的值。我的解决方案是:git log | sed-n'0,/.[git-p4:.\/\/depot\/blah\/([^\/]*)\/./s/\1/p/[git-p4/q'不幸的是,在macOS
上的q命令末尾出现了一个错误
。解决方法很简单:在q:
{s//\1/p;q;}
grep --max-count 1 'something'