예를 들어 다음 내용이 포함된 파일이 있습니다.
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