user23146 Asked: 2019-03-29 01:39:40 +0800 CST2019-03-29 01:39:40 +0800 CST 2019-03-29 01:39:40 +0800 CST 仅在找到模式后打印输出 772 有一个脚本(我们称之为echoer)打印以筛选一堆信息。我希望在找到模式后才能看到线条。 我想象一个解决方案的使用看起来像 echoer | solution_command <pattern> 理想情况下pattern将是一个正则表达式,但硬值字符串对我来说就足够了。 echo printf 6 个回答 Voted Best Answer Stephen Kitt 2019-03-29T01:46:13+08:002019-03-29T01:46:13+08:00 AWK 可以使用模式范围来做到这一点,它允许使用任何正则表达式: echoer | awk '/pattern/,0' 将从第一行匹配开始打印echoer的输出pattern。 AWK 是基于模式的,通常与“如果此模式匹配,则执行此操作”类型的方法一起使用。“这个模式”可以是一系列模式,定义为“当这个模式匹配时,开始这样做,直到另一个模式匹配”;这是通过写两个用逗号分隔的模式来指定的,如上所述。模式可以是文本匹配,如在 中/pattern/,根据模式检查当前行,解释为正则表达式;它们也可以是通用表达式,对每一行进行评估,如果它们的结果非零或非空,则认为匹配。 在 AWK 中,默认操作是打印当前行。 将所有这些放在一起,awk '/pattern/,0'查找匹配的行pattern,一旦找到,将默认操作应用于所有行,直到0条件匹配(非零)。awk '/pattern/,""'也可以。 Gawk手册更详细。 Stéphane Chazelas 2019-03-29T06:48:14+08:002019-03-29T06:48:14+08:00 sed@StephenKitt 的强制性等价物awk: sed '/pattern/,$!d' pattern这里被解释为一个基本正则表达式,如 in grep(与/ /中的扩展正则表达式相反)。一些实现有一个(BSD,ast,最近的 GNU/busybox,很快 POSIX)或(GNU,ssed,busybox,一些最近的 BSD)选项来使其成为扩展正则表达式,而有些实现具有(ast) 或(ssed) 来实现一个类似 perl 的正则表达式。awkegrepgrep -Esed-E-r-P-R 与perl: perl -ne 'print if /pattern/ .. undef' mosvy 2019-03-29T06:55:28+08:002019-03-29T06:55:28+08:00 使用 GNU 和 *BSD grep: grep -A1000000000 pattern file 除非您的文件有超过 1M 行,否则就是这样。 wjandrea 2019-03-29T18:18:56+08:002019-03-29T18:18:56+08:00 重击 有点笨拙,但它有效。 #!/bin/bash found=false while IFS= read -r; do if $found || [[ $REPLY =~ pattern ]]; then found=true printf '%s\n' "$REPLY" fi done 这个版本依赖于cat,但更容易理解。 #!/bin/bash while IFS= read -r; do if [[ $REPLY =~ pattern ]]; then printf '%s\n' "$REPLY" break fi done cat iruvar 2019-03-29T18:29:24+08:002019-03-29T18:29:24+08:00 如果您正在使用寻呼机,例如less查看命令的输出 less +pattern Gaultheria 2019-03-29T18:53:19+08:002019-03-29T18:53:19+08:00 awk对于(但不包括)第一个模式匹配之后的行 如果包含触发模式的行相当于“CUT HERE”,则可以从打印输出中省略它: echoer | awk 'flag ; /pattern/ { flag=1 }' 每一行输入都经过 awk 代码中的两个组件。第一个组件是flag,awk 将其解释为“如果变量flag非零则打印该行”。由于 awk 变量默认为 0,因此最初不会打印任何内容。 第二个组件 ,/pattern/ { flag=1 }一旦检测到该模式,就会将标志设置为 1,并且该标志会在剩余的运行中保持该值。 到第一次检测到模式时,打印该行输入的机会已经过去。任何后续行(包括包含该模式的其他行)都将打印。
AWK 可以使用模式范围来做到这一点,它允许使用任何正则表达式:
将从第一行匹配开始打印
echoer
的输出pattern
。AWK 是基于模式的,通常与“如果此模式匹配,则执行此操作”类型的方法一起使用。“这个模式”可以是一系列模式,定义为“当这个模式匹配时,开始这样做,直到另一个模式匹配”;这是通过写两个用逗号分隔的模式来指定的,如上所述。模式可以是文本匹配,如在 中
/pattern/
,根据模式检查当前行,解释为正则表达式;它们也可以是通用表达式,对每一行进行评估,如果它们的结果非零或非空,则认为匹配。在 AWK 中,默认操作是打印当前行。
将所有这些放在一起,
awk '/pattern/,0'
查找匹配的行pattern
,一旦找到,将默认操作应用于所有行,直到0
条件匹配(非零)。awk '/pattern/,""'
也可以。Gawk手册更详细。
sed
@StephenKitt 的强制性等价物awk
:pattern
这里被解释为一个基本正则表达式,如 ingrep
(与/ /中的扩展正则表达式相反)。一些实现有一个(BSD,ast,最近的 GNU/busybox,很快 POSIX)或(GNU,ssed,busybox,一些最近的 BSD)选项来使其成为扩展正则表达式,而有些实现具有(ast) 或(ssed) 来实现一个类似 perl 的正则表达式。awk
egrep
grep -E
sed
-E
-r
-P
-R
与
perl
:使用 GNU 和 *BSD grep:
除非您的文件有超过 1M 行,否则就是这样。
重击
有点笨拙,但它有效。
这个版本依赖于
cat
,但更容易理解。如果您正在使用寻呼机,例如
less
查看命令的输出awk
对于(但不包括)第一个模式匹配之后的行如果包含触发模式的行相当于“CUT HERE”,则可以从打印输出中省略它:
每一行输入都经过 awk 代码中的两个组件。第一个组件是
flag
,awk 将其解释为“如果变量flag
非零则打印该行”。由于 awk 变量默认为 0,因此最初不会打印任何内容。第二个组件 ,
/pattern/ { flag=1 }
一旦检测到该模式,就会将标志设置为 1,并且该标志会在剩余的运行中保持该值。到第一次检测到模式时,打印该行输入的机会已经过去。任何后续行(包括包含该模式的其他行)都将打印。