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