考虑以下范围:1,/pattern/
. 如果模式在第一行匹配,则整个文件的范围匹配:
$ cat 1.sh
#!/usr/bin/env bash
set -eu
seq 1 4 | sed -rn '1,/'"$1"'/p'
$ ./1.sh 1
1
2
3
4
$ ./1.sh 2
1
2
Run Code Online (Sandbox Code Playgroud)
你会怎么做?
UPD这是我所做的(以防万一):
re='/1/'
seq 1 4 | sed -rn "1{$re{p;q}}; 1,${re}p"
Run Code Online (Sandbox Code Playgroud)
或者这样:
seq 1 4 | sed -rn "1{/1/{p;q}}; 1,//p"
Run Code Online (Sandbox Code Playgroud)
是的,这是一件令人讨厌的事情sed
(请参阅有关该sed
问题的常见问题解答)。由于您使用的是 GNU sed
(-r
特定于 GNU),您可以执行以下操作:
sed -En "0,/$1/p"
Run Code Online (Sandbox Code Playgroud)
(我更喜欢它-E
,-r
因为它也受其他一些工具的支持,sed
例如 FreeBSD,并且与grep
其他一些工具一致(并且将在下一期的 POSIX/Single UNIX 规范标准中介绍))。
一个更好的选择(和便携)是:
sed "/$1/q"
Run Code Online (Sandbox Code Playgroud)
sed
在第一场比赛后告诉退出(并停止阅读)。
请注意,awk
没有问题,因此您可以编写:
PATTERN=$1 awk 'NR==1, $0 ~ ENVIRON["PATTERN"]'
Run Code Online (Sandbox Code Playgroud)
(虽然像 for sed
,你宁愿写):
PATTERN=$1 awk '1; $0 ~ ENVIRON["PATTERN"] {exit}'
Run Code Online (Sandbox Code Playgroud)