Regex SED:在匹配前寻址两行
打印行,位于匹配(图案)前2行 我下一步尝试:Regex SED:在匹配前寻址两行,regex,unix,sed,Regex,Unix,Sed,打印行,位于匹配(图案)前2行 我下一步尝试: sed -n ': loop /.*/h :x {n;n;/cen/p;} s/./c/p t x s/n/c/p t loop {g;p;} ' datafile 如果可以使用awk请尝试以下操作: awk '/pattern/ {print b} {b=a;a=$0}' file 这将在模式之前打印两行我已经测试了您的命令,但结果很奇怪(显然是错误的),您没有给出任何解释。您必须在缓冲区中保存三行(名为保留空间),使用最新的行进行模式搜索
sed -n ': loop
/.*/h
:x
{n;n;/cen/p;}
s/./c/p
t x
s/n/c/p
t loop
{g;p;}
' datafile
如果可以使用
awk
请尝试以下操作:
awk '/pattern/ {print b} {b=a;a=$0}' file
这将在模式之前打印两行
我已经测试了您的命令,但结果很奇怪(显然是错误的),您没有给出任何解释。您必须在缓冲区中保存三行(名为保留空间),使用最新的行进行模式搜索,如果匹配,则打印最旧的一行:
sed -n '
## At the beginning read three lines.
1 { N; N }
## Append them to "hold space". In following iterations it will append
## only one line.
H
## Get content of "hold space" to "pattern space" and check if the
## pattern matches. If so, extract content of first line (until a
## newline) and exit.
g
/^.*\nsix$/ {
s/^\n//
P
q
}
## Remove the old of the three lines saved and append the new one.
s/^\n[^\n]*//
h
' infile
假设并输入包含以下内容的文件(infle
):
one
two
three
four
five
six
seven
eight
nine
ten
它将搜索六个,作为输出将产生:
four
剧本:
sed -n "1N;2N;/XXX[^\n]*$/P;N;D"
工作内容如下:
- 将前三行读入模式空间,
1N;2N
- 在最后一行的任意位置搜索测试字符串
,如果找到,打印模式空间的第一行,XXX
P
- 将下一行输入追加到模式空间,
N
- 从模式空间中删除第一行,重新开始循环,不进行任何新的读取,
,注意D
不再适用1N;2N
这将在整个文件中打印
模式
前的第2行。这一行使用grep,这是一种更简单的解决方案,易于阅读[但需要使用一个管道]:
grep-B2'pattern'文件名| sed-n'1,2p'
以下是一些其他变体:
awk '{a[NR]=$0} /pattern/ {f=NR} END {print a[f-2]}' file
这会将所有行存储在数组a
中。当找到模式时,存储行号。最后,打印文件中的行号。
PS在处理大文件时可能速度较慢
这里还有一个:
awk 'FNR==NR && /pattern/ {f=NR;next} f-2==FNR' file{,}
这将读取文件两次(文件{,}
与文件
相同)在第一轮中,它查找模式并将行号存储在变量
f
然后在第二轮中,它在
f
中的值前面打印第二行,这是一个很好的问题,答案很漂亮。单行文件应始终不提供任何内容。但是如果该行是模式
,此脚本将打印它。-1这将只处理文件中的第一个匹配模式(尽管OP的问题不清楚)。这只打印匹配前的第二行,如果您需要匹配前的第二行和第一行,请尝试awk'/^commit./{print b'\n“a}{b=a;a=$0}'文件
awk 'FNR==NR && /pattern/ {f=NR;next} f-2==FNR' file{,}