如何使用grep / awk / sed打印所有字符,直到某个模式(不包括模式本身)。

例如

echo "abc-1234a :" | grep <do-something> 

打印abc-1234a

我认为这些更接近你所得到的,但是不知道你真的想达到什么目的,这很难说。

 echo "abc-1234a :" | egrep -o '^[^:]+' 

…虽然这也将匹配没有冒号的线。 如果你只想要冒号的行,而且只能使用grep,这可能会起作用:

 echo "abc-1234a :" | grep : | egrep -o '^[^:]+' 

当然,这只有在你的echo "abc-1234a :"是一个可能被多行输入代替的例子时才有意义。

你可以使用的最小的工具可能是cut

 echo "abc-1234a :" | cut -d: -f1 

sed总是可用的…

 echo "abc-1234a :" | sed 's/ *:.*//' 

对于最后一个,如果您只想打印包含冒号的行,请将其更改为:

 echo "abc-1234a :" | sed -ne 's/ *:.*//p' 

哎呀,你甚至可以在纯粹的bash中做到这一点:

 while read line; do field="${line%%:*}" # do stuff with $field done <<<"abc-1234a :" 

有关%%位的信息,您可以打开并搜索“ 参数扩展 ”。

更新

你说:

这是冒号前面第一行输入的字符。 输入可能有多行。

grep解决方案可能不是你的最佳选择,那么,因为他们还会打印可能包含冒号的后续行的数据。 当然,解决这个需求的方法也有很多。 我们将从样本输入开始:

 $ function sample { printf "abc-1234a:foo\nbar baz:\nNarf\n"; } $ sample abc-1234a:foo bar baz: Narf 

您可以使用多个管道,例如:

 $ sample | head -1 | grep -Eo '^[^:]*' abc-1234a $ sample | head -1 | cut -d: -f1 abc-1234a 

或者你可以使用sed只处理第一行:

 $ sample | sed -ne '1s/:.*//p' abc-1234a 

或者告诉sed在打印第一行之后退出(这比读取整个文件要快):

 $ sample | sed 's/:.*//;q' abc-1234a 

或者做同样的事情,但只显示输出,如果冒号被找到(为了安全):

 $ sample | sed -ne 's/:.*//p;q' abc-1234a 

或者让awk做同样的事情(分别是最后3个例子):

 $ sample | awk '{sub(/:.*/,"")} NR==1' abc-1234a $ sample | awk 'NR>1{nextfile} {sub(/:.*/,"")} 1' abc-1234a $ sample | awk 'NR>1{nextfile} sub(/:.*/,"")' abc-1234a 

或在bash中,根本没有管道:

 $ read line < <(sample) $ printf '%s\n' "${line%%:*}" abc-1234a