たとえば、次の内容のファイルがあります。
eggs
bacon
cereal
eggs
bacon
cheese
cereal
出力:
eggs
bacon
cereal
eggs
この例では、と という単語の間の行を削除したいのですcereal
が、cheese
間に が含まれている場合のみです。
を使ってこれをどうやったらできるでしょうか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"
パターンの間に文字列が見つかった場合のみ、 から を削除したいのですが、"crosshair"
テキストファイルには を含む他のコード ブロックがあります。}
"sprites/crosshairs"
"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