![删除 2 个模式之间的行,但前提是中间有特定的字符串](https://linux22.com/image/95331/%E5%88%A0%E9%99%A4%202%20%E4%B8%AA%E6%A8%A1%E5%BC%8F%E4%B9%8B%E9%97%B4%E7%9A%84%E8%A1%8C%EF%BC%8C%E4%BD%86%E5%89%8D%E6%8F%90%E6%98%AF%E4%B8%AD%E9%97%B4%E6%9C%89%E7%89%B9%E5%AE%9A%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
例如,我有一个包含以下内容的文件:
eggs
bacon
cereal
eggs
bacon
cheese
cereal
输出:
eggs
bacon
cereal
在示例中,我想删除单词eggs
and之间的行cereal
,但前提是它包含cheese
in 之间。
我怎样才能使用 来做到这一点sed
?
我被要求更具体,所以这基本上就是我想做的,我希望这能让它更清楚:
WeaponData
{
TextureData
{
"crosshair"
{
"file" "vgui/replay/thumbnails/"
"x" "0"
"y" "0"
"width" "64"
"height" "64"
}
"weapon"
{
"file" "sprites/bucket_bat_red"
"x" "0"
"y" "0"
"width" "200"
"height" "128"
}
"weapon_s"
{
"file" "sprites/bucket_bat_blue"
"x" "0"
"y" "0"
"width" "200"
"height" "128"
}
"ammo"
{
"file" "sprites/a_icons1"
"x" "55"
"height" "15"
}
"crosshair"
{
"file" "sprites/crosshairs" <---
"x" "32"
"y" "32"
"width" "32"
"height" "32"
}
"autoaim"
{
"file" "sprites/crosshairs"
"x" "0"
"y" "48"
"width" "24"
"height" "24"
}
}
}
这是我尝试过的命令:
sed '/"crosshair"/,/}/d' file.txt
该命令只是从第一个"crosshair"
到最后一个删除}
,无论"sprites/crosshairs"
中间是否有行。
我只想删除 from"crosshair"
到}
if 在模式之间"sprites/crosshairs"
找到字符串。但是,包含 .txt 的文本文件上还有其他代码块"sprites/crosshairs"
。
例如:
"autoaim"
{
"file" "sprites/crosshairs"
"x" "0"
"y" "48"
"width" "24"
"height" "24"
}
这是无法删除的。我对没有早点解释这一点深表歉意,但我认为没有必要。
don_crissti 的建议非常有效,即sed '/crosshair/,/\}/{H;/\}/!d;s/.*//;x;/sprites\/crosshairs/d;s/.//;}' infile
然而,输出是这样的:
... "autoaim" { } }
"autoaim"
已部分删除,但未完全删除,但正如您所看到的,包含的块"sprites/crosshairs"
已被删除,正如我想做的那样,但autoaim
仍然无法修改
答案1
sed '/^[[:blank:]]*"crosshair"/,/}/{H;/}/!d;s/.*//;x;/sprites\/crosshairs/d;s/.//;}' infile
怎么运行的:
sed '/^[[:blank:]]*"crosshair"/,/}/{ # in this range
H # append each line to hold buffer
/}/!d # delete it if not the end of range
s/.*// # empty the pattern space
x # exchanges buffers
/sprites\/crosshairs/d # delete pattern space if it matches
s/.// # remove leading newline, autoprint
}' infile
这假设匹配的行后面^[[:blank:]]*"crosshair"
总是跟着大括号括起来的行块,就像您的示例中一样。
答案2
如果perl
可以,可以使用段落模式(-00
选项)并使用多行正则表达式匹配
$ cat ip.txt
eggs
bacon
cereal
eggs
bacon
cheese
cereal
$ perl -00 -ne 'print if !/^eggs.*cheese.*cereal$/ms' ip.txt
eggs
bacon
cereal