awk - 如何使用 grep/awk/sed 打印特定模式(不包括模式本身)之前的所有字符?

标签 awk sed grep

例如

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

有关%% 位的信息,您可以man bash 并搜索“Parameter Expansion”。

更新:

你说:

It's the characters in the first line of input before the colon. The input could have multiple line though.

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

关于awk - 如何使用 grep/awk/sed 打印特定模式(不包括模式本身)之前的所有字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12360942/

相关文章:

unix - 根据模式拆分文件或提取不同的行

awk - 使用 sed 或 awk 替换文本 block

shell - 一行中的多个字符串的 grep

bash - awk 在 linux 终端中输出类似表或类似 excel 的列?

linux - 我想检查第一列中的数字是否等于第二列,第一列应以以下格式开始和结束

linux - 如何通过 bash 脚本中的管道从命令中提取 2 条信息输出?

regex - 我如何替换在 linux 中特定文件夹中找到的所有电子邮件地址

regex - 破译正则表达式

linux - 根据值为每个条目提取记录子集

regex - Grep 在 OpenBSD 和 Linux 中的行为不同。无法使命令工作