例如,我有一个包含以下内容的文件:
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