使用sed或awk打印符合匹配图案的线条
问题:我想在包含匹配图案的行后面直接打印一行 我的使用sed或awk打印符合匹配图案的线条,awk,sed,Awk,Sed,问题:我想在包含匹配图案的行后面直接打印一行 我的sed版本不会采用以下语法(它在+1p上爆炸),这似乎是一个简单的解决方案: sed -n '/ABC/,+1p' infile 我认为多行处理比awk更好,但我不知道怎么做。这是你感兴趣的匹配后的行,对吗?在sed中,可以这样完成: sed -n '/ABC/{n;p}' infile 或者,grep的选项可能就是您想要的 -A NUM, Print NUM lines of trailing context after matching
sed
版本不会采用以下语法(它在+1p
上爆炸),这似乎是一个简单的解决方案:
sed -n '/ABC/,+1p' infile
我认为多行处理比awk更好,但我不知道怎么做。这是你感兴趣的匹配后的行,对吗?在sed中,可以这样完成:
sed -n '/ABC/{n;p}' infile
或者,grep的选项可能就是您想要的
-A NUM, Print NUM lines of trailing context after matching lines.
例如,给定以下输入文件:
foo
bar
baz
bash
bongo
您可以使用以下选项:
$ grep -A 1 "bar" file
bar
baz
$ sed -n '/bar/{n;p}' file
baz
希望这会有帮助。你对那场比赛后的台词感兴趣,对吗?在sed中,可以这样完成:
sed -n '/ABC/{n;p}' infile
或者,grep的选项可能就是您想要的
-A NUM, Print NUM lines of trailing context after matching lines.
例如,给定以下输入文件:
foo
bar
baz
bash
bongo
您可以使用以下选项:
$ grep -A 1 "bar" file
bar
baz
$ sed -n '/bar/{n;p}' file
baz
希望对您有所帮助。awk版本:
awk '/regexp/ { getline; print $0; }' filetosearch
awk版本:
awk '/regexp/ { getline; print $0; }' filetosearch
永远不要使用“模式”这个词,因为它是高度模糊的。始终使用“string”或“regexp”(或shell中的“globbing模式”),无论您真正的意思是什么
您想要的具体答案是:
awk 'f{print;f=0} /regexp/{f=1}' file
或者在regexp之后专门化第n条记录的更一般的解决方案(下面的习惯用法“c”):
以下习惯用法描述了如何选择给定要匹配的特定regexp的记录范围:
a) 打印某些regexp中的所有记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
b) 在某些regexp之后打印所有记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
c) 在某些regexp之后打印第n条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
d) 在某些regexp之后打印除第n条记录以外的每条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
e) 在一些regexp之后打印N条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
f) 打印除某些regexp之后的N条记录以外的每条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
g) 打印某些regexp中的N条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
我将变量名从“found”的“f”改为“count”的“c”,其中
适当,因为这更能表达变量的实际含义。切勿使用“模式”一词,因为它非常模糊。始终使用“string”或“regexp”(或shell中的“globbing模式”),无论您真正的意思是什么
您想要的具体答案是:
awk 'f{print;f=0} /regexp/{f=1}' file
或者在regexp之后专门化第n条记录的更一般的解决方案(下面的习惯用法“c”):
以下习惯用法描述了如何选择给定要匹配的特定regexp的记录范围:
a) 打印某些regexp中的所有记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
b) 在某些regexp之后打印所有记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
c) 在某些regexp之后打印第n条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
d) 在某些regexp之后打印除第n条记录以外的每条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
e) 在一些regexp之后打印N条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
f) 打印除某些regexp之后的N条记录以外的每条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
g) 打印某些regexp中的N条记录:
awk '/regexp/{f=1}f' file
awk 'f;/regexp/{f=1}' file
awk 'c&&!--c;/regexp/{c=N}' file
awk 'c&&!--c{next}/regexp/{c=N}1' file
awk 'c&&c--;/regexp/{c=N}' file
awk 'c&&c--{next}/regexp/{c=N}1' file
awk '/regexp/{c=N}c&&c--' file
我将变量名从“found”的“f”改为“count”的“c”,其中
适当,因为这更能表达变量的实际含义。如果模式匹配,则将下一行复制到模式缓冲区,删除一个返回,然后退出——副作用是打印
sed '/pattern/ { N; s/.*\n//; q }; d'
若模式匹配,将下一行复制到模式缓冲区,删除一个返回,然后退出——副作用是打印
sed '/pattern/ { N; s/.*\n//; q }; d'
我需要打印模式之后的所有行(ok Ed,REGEX),因此我决定使用这一行:
sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern
但是因为我想打印后面的所有行(并排除模式)
我想在您的案例中,您可以在末尾添加一个head-1
sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern
我需要打印模式之后的所有行(ok Ed,REGEX),因此我决定使用这一行:
sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern
但是因为我想打印后面的所有行(并排除模式)
我想在您的案例中,您可以在末尾添加一个head-1
sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern
实际上,如果
模式
匹配连续
行,则sed-n'/pattern/{n;p}文件名
将失败:
$ seq 15 |sed -n '/1/{n;p}'
2
11
13
15
预期的答案应该是:
2
11
12
13
14
15
我的解决办法是:
$ sed -n -r 'x;/_/{x;p;x};x;/pattern/!s/.*//;/pattern/s/.*/_/;h' filename
例如:
$ seq 15 |sed -n -r 'x;/_/{x;p;x};x;/1/!s/.*//;/1/s/.*/_/;h'
2
11
12
13
14
15
说明:
x代码>:在输入的每一行的开头,使用x
命令交换模式空间中的内容
&保持空间
/{x;p;x}代码>:如果模式空间
(实际上是保留空间
)包含
(这只是一个指示器
,指示最后一行是否与模式
匹配),则使用x
将当前行
的实际内容交换到模式空间
,使用p
打印当前行
,使用x
恢复此操作李>
x
:恢复图案空间
和保留空间
中的内容
/pattern/!s/*/
:如果当前行
与模式
不匹配,这意味着我们不应打印下一行,则使用s/*/
命令删除模式空间
中的所有内容
/pattern/s/*/
:如果当前行
与模式
匹配,这意味着我们应该打印下一行,那么我们需要设置一个指示器
告诉sed
打印下一行,因此使用s/*/
将模式空间
中的所有内容替换为(第二个命令将使用它来判断最后一行是否与模式匹配)
h
:用模式空间中的内容覆盖保留空间
;然后,保留空间
中的内容是^$
,这意味着当前行
与模式
匹配,或者^$
,这意味着当前行
与模式
不匹配
第五步和第六步不能交换,因为在s/*/
之后,模式空间
不能匹配/pattern/
,所以必须执行s/*/
实际上sed-