刪除 2 個模式之間的行,但前提是其間有特定字串

刪除 2 個模式之間的行,但前提是其間有特定字串

例如,我有一個包含以下內容的文件:

eggs
bacon
cereal

eggs
bacon
cheese
cereal

輸出:

eggs
bacon
cereal

在範例中,我想刪除單字eggsand之間的行cereal,但前提是它包含cheesein 之間。

我怎樣才能使用 來做到這一點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

相關內容