我只需要打印每行的第一场比赛。
我的文件包含如下文本:
cat t.txt
abcsuahrcb
abscuharcb
bsaucharcb
absuhcrcab
他是我正在尝试的命令:
cat t.txt | grep -oP 'a.*?c'
它给出:
abc
ahrc
absc
arc
auc
arc
absuhc
我需要它返回:
abc
absc
auc
absuhc
这些是每行的第一个可能的匹配项。
任何其他替代方案,如sed和aws都可以工作,但不是需要在Ubuntu上安装的东西。
Perl 来救援:
perl -lne 'print $1 if /(a.*?c)/' t.txt
-n
逐行读取输入,为每个输入运行代码;-l
从输入行中删除换行符并将它们添加到输出中;- 代码尝试匹配
a.*?c
,如果匹配,它将结果存储在 $1 中; - 由于没有循环,因此每行只尝试一场比赛。
第四只鸟的答案的sed
变体:
$ sed -En 's/^[^a]*(a[^c]*c).*/1/p' t.txt
abc
absc
auc
absuhc
哪里:
-En
- 启用扩展正则表达式支持,禁止自动打印模式空间^[^a]*
- 从行首匹配所有未a
的后续字符(a[^c]*c)
- (第 1 个捕获组)匹配字母a
加上所有未c
后跟c
的后续字符.*
- 匹配行的其余部分1/p
- 打印第一个捕获组的内容
一个awk
想法:
$ awk 'match($0,/a[^c]*c/) { print substr($0,RSTART,RLENGTH)}' t.txt
abc
absc
auc
absuhc
哪里:
- 如果我们找到匹配项,则
match()
调用为非零(即"true"),因此... - 打印由
RSTART/RLENGTH
变量定义的substr
(由成功的match()
调用自动填充)
使用grep
您可以使用否定字符类将模式编写为从第一个a
到第一个c
的匹配。
使用 Perl 兼容正则表达式的-P
,您可以使用K
来忘记到目前为止匹配的内容。
请注意,您不必使用cat
,但您可以在末尾添加文件名。
grep -oP '^[^a]*Ka[^c]*c' t.txt
模式匹配:
^
字符串开头[^a]*
可选匹配除a
之外的任何字符K
忘记到目前为止匹配的内容a
字面意思匹配[^c]*
可选匹配除c
以外的任何字符c
字面意思匹配
输出
abc
absc
auc
absuhc
另一个具有gnu-awk
和相同模式的选项,只是现在使用和打印捕获组 1 值:
awk 'match($0,/^[^a]*(a[^c]*c)/, a) { print a[1]}' t.txt