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