我有一个大文件(超过 2000 行)。找到模式后,我必须在上面 2 行的开头和下面 1 行的开头插入 # 。还在找到模式的行的开头插入#。环境是Red Hat Linux。另外,如果您能解释一下,那就太好了。
举个例子,请参阅下面的文本,搜索“Fail”以及该字符串之前的 # 2 行和该字符串之后的 1 行(行首)。另外 # 行包含字符串“Fail”。
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Fail
Reasult
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Fail
Reasult
Name
Number
Reason = Pass
Reasult
答案1
我建议使用perl
:
perl -p0e 's/(.*\n)(.*\n)(.*Fail\n)/#\1#\2#\3#/g' file
下面是它的工作原理:
-p
:在所有输入行上循环打印程序-0
: 假设 null 作为记录分隔符-e
:从命令行执行程序s/x/y/g
:在文件中的任意位置用 y 替换 x()
:将正则表达式组合在一起.*
:除换行符之外的任何字符重复零次或多次\n
: 新队\1
,\2
,\3
: 第 n 组的访问模式()
输出:
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
答案2
这是sed
使用滑动窗口的解决方案(因此模式空间中一次不会超过四行):
sed '1{N;N;};$!N;/.*\n.*\n.*Fail.*\n.*/{s/^/#/;s/\n/&#/g;};P;D' infile
在第一行,它读入N
后两行(所以现在模式空间中有三行)。
然后,对于每个输入行(包括第一行),它都会拉入N
ext 行(因此现在模式空间中有四行)。如果模式空间中的第三行匹配Fail
,它会在模式空间中的每一行前面添加一个#
。然后,无论如何,它P
都会 rint 到第一个\n
ewline,然后D
eletes 到第一个\n
ewline,重新开始循环。
答案3
$ sed -r 'H;1h;$!d;x; s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g' file
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
怎么运行的
H;1h;$!d;x
这些命令读取整个文件。
s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g
Fail
这将查找第三行中的连续四行。如果找到,则将#
其放置在每个换行符之后。更详细地说,替换命令看起来像正则表达式
s/old/new
where 。old
在我们的例子中,它是\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n
。让我们将其分为四个部分:\n([^\n]*)
找到第一行并将其保存在组 1 中。\n([^\n]*)
找到第二行并将其保存在组 2 中。\n([^\n]*Fail[^\n]*)
查找第三行,但仅当该行包含该单词时才匹配Fail
。\n
匹配第四个换行符。 (第四行的文本未保存:我们不需要它。)
如果有四行与上面的匹配,那么我们将它们替换为
\n#\1\n#\2\n#\3\n#
输入相同的内容,除了#
在每个换行符之后添加的\n
。Mac OSX (BSD)
以上是在 GNU sed 上测试的。如果使用 BSD sed,请尝试:
sed -E 'H;1h;$!d;x; s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g' file
答案4
更简单的变体@don_crissti的脚本
sed ':a;/\(.*\n\)\{2\}/{P;D};N;/= Fail$/! ba;N;s/^/# /gm'