我试图从文件中删除模式匹配的所有实例(如果它与模式匹配)。如果存在匹配,则具有匹配模式的(完整)行和下一行将被删除。
下一行始终出现在模式匹配的行之后,但除此之外它还出现在文件的其他区域中。
我正在使用 grep,它会按预期删除文件中下一行的所有出现位置。
有没有一种方法可以删除下一行当且仅当它位于模式匹配的行之后?
答案1
答案2
如果您打开,大多数sed
s 不会打印最后一行。但 GNU会的。因此,如果您要删除的图案位于最后一行,它就会打印出来。有时最好保持缓冲区满 - 例如,始终保留 2 行N
$
sed
N
除了在您不想打印的行上。你可能会这样做:
seq 10 | sed -n 'x;/7/!g;//!p'
这是一个作为输入的示例seq
。在每一行上,它都会交换保持空间和模式空间。如果最后保留的行与7
(在这种情况下)它将用当前行覆盖保留空间。然后它再次检查刚刚拉入的行(当前行)是否也与 不匹配7
,否则它不会打印它。因此,它在每一行都会检查前一行和当前行。
1
2
3
4
5
6
9
10
如果你的模式确实落在最后一行:
seq 10 | sed -n 'x;/10/!g;//!p'
1
2
3
4
5
6
7
8
9
另一个例子,希望更清楚地展示它将打印什么和不会打印什么:
sed -n 'x;/match/!g;//!p
' <<\DATA
match
match
1not
2not
3not
4not
5not
match
6not
match
DATA
输出
2not
3not
4not
5not
答案3
awk 解决方案:
awk '/pattern/ { matched=1; next }
1 == matched { matched = 0; next }
{ print }' input-file
第 1 行查找与模式匹配的行,设置标志并跳过该行。第 2 行在设置标志时跳过一行,但重置标志。第 3 行打印未被其他两行之一跳过的行。
如果您愿意,可以在一行中输入:
awk '/pattern/{matched=1;next} 1==matched{matched=0;next} {print}' input-file
这是一个变体,可以让您控制要跳过的行数:
awk '/pattern/{skip=3;next} skip>0{--skip;next} {print}' input-file
设置skip
为应跳过的行数(除了匹配的行之外)。
答案4
怎么样
sed '/pattern/ {$!N;d;}' file