두 패턴 사이의 줄을 삭제합니다. 단, 그 사이에 특정 문자열이 있는 경우에만 해당됩니다.

두 패턴 사이의 줄을 삭제합니다. 단, 그 사이에 특정 문자열이 있는 경우에만 해당됩니다.

예를 들어 다음 내용이 포함된 파일이 있습니다.

eggs
bacon
cereal

eggs
bacon
cheese
cereal

산출:

eggs
bacon
cereal

eggs이 예에서는 and라는 단어 사이의 줄을 삭제하고 싶습니다 cereal. 단, in이 포함된 경우에만 해당됩니다 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"

패턴 사이의 문자열을 찾기 위해 from "crosshair"to if 를 제거하고 싶습니다 . 그러나 .txt 가 포함된 텍스트 파일에는 다른 코드 블록이 있습니다 .}"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

관련 정보