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

时间:2012-09-10 23:52:44

标签: linux command-line sed awk grep

例如

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

只打印abc-1234a

1 个答案:

答案 0 :(得分:17)

我认为这些更接近你的目标,但不知道你真正想要达到的目标,很难说。

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 :"

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

<强>更新

你说:

  

这是冒号前第一行输入中的字符。该   输入可以有多行。

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