다음과 같은 데이터 세트가 있습니다.
\"XXX \ START sapiodj \\" aj \d 2387 END hddo\" START bbcc \\" END ss
\
내 요구 사항: START와 END 사이에 있는 모든 백슬래시와 큰따옴표를 제거하고 싶습니다 ."
원하는 출력:
\"XXX \ START sapiodj aj d 2387 END hddo\" START bbcc END ss
노트:
- 같은 줄에 여러 개의 START/END
- 다른 곳에서는 삭제하지 않고 START 와 END 사이의
\
및 만 삭제하고 싶습니다."
- 내 파일에 여러 줄이 있습니다(위에 표시된 것과 유사).
sed
그냥 사용해야겠어요
다음과 같은 방법을 시도했지만( "
먼저 개별적으로 제거하려고 시도) 원하는 결과를 얻지 못했습니다.
sed '/START/,/END/ s/"//g'
답변1
`
파일에 문자가 없다고 가정합니다. 아래의 모든 줄을 다른 문자로 변경하면 `
해당 문자는 입력에 나타나지 않습니다.
sed -e 's/END/`/g;:X' -e 's/\(START[^`]*\)["\]/\1/g;tX' -e 's/`/END/g'
답변2
실제로 그것은 어렵지 않습니다 sed
. \n
섹션을 분리하려면 언제든지 ewline을 사용할 수 있습니다.또는\n
임시로 구분 기호를 ewline으로 변경할 수 있습니다.그리고루프 없이 이 작업을 수행할 수 있습니다.
sed 's/$/START/;s/END/&
/g; y/D\n/\nD/
s/\([^D]*START\)*[D\"]*/\1/g
y/\n/D/;s/.....$//
' <<\IN
\"XXX \ START sapiodj \\" aj \d 2387 END hddo\" START bbcc \\" END ss
IN
때로는 사물을 다르게 생각해야 할 때도 있습니다. 사이에 있는 모든 것을 삭제하는 대신 줄의 시작과 문자열, 줄의 마지막과 끝 사이에 발생할 때만 저장하는 방법에 대한 질문을 돌리는 것이 더 쉬울 것 입니다 \\"
.START
END
\\"
START
START
END
END
(물론 이것이 직관적으로 사실이 아니라면). 이는 0개 이상의 일치 항목이 sed
처리되는 방식 때문입니다.*
g
현지 s///
대체문맥.
처음부터 첫 번째 START
비트는 나머지 비트의 자연스러운 결과로 지워지지 만 END
마지막부터 끝까지의 비트는 지워지지 않습니다. 따라서 START
줄 끝에 다른 비트를 추가해야 합니다. 추가 콘텐츠를 얻은 후 각 항목에 ewline 문자를 추가 START
합니다 . 그런 다음 음역 명령을 사용하여 모든 문자를 동시에 ewline으로 바꾸거나 그 반대로 바꿉니다. 그런데 여기에서는 음역 명령이 매우 편리할 뿐만 아니라 대체 명령보다 더 효율적입니다.\n
END
y///
D
\n
y///
s///
이 시점에서 l
패턴 공간은 다음과 같이 인쇄됩니다.
\\"XXX \\ START sapiodj \\\\" aj \\d 2387 EN\nD hddo\\" START bbcc \\\\" EN\nD ssSTART$
보시다시피, 이제 \\"
저장해야 하는 모든 문자가 줄의 시작 부분이나 D
a와 문자열 사이에 있고 그 사이에 s가 없습니다 START
. D
따라서 원하지 않는 문자(추가 s 포함)를 제거하는 전역 대체는 g
자체적으로 저장해야 하는 문자도 대체합니다. 마지막으로 와 s를 다시 바꾸고 마지막 항목을 삭제하면 됩니다.s///
D
\n
D
START
이렇게 하면 필드를 안정적으로 구분할 수 있습니다.sed
입력에 관계없이그리고 표시되지 않는 문자에 의존하는 것이 아니라 줄에 절대 표시되지 않는 문자( \n
물론 ewline 문자)에 의존합니다.
완료되면 인쇄하십시오.
\"XXX \ START sapiodj aj d 2387 END hddo\" START bbcc END ss
답변3
그리고 sed
:
sed 's/:/::/g;s/</:l/g;s/>/:g/g; # escape :, <, >
s/START/&</g; s/END/>&/g; # replace START/END with <>
:1
s/\(<[^>]*\)[\"]/\1/g;t1
s/[<>]//g;s/:g/>/g;s/:l/</g;s/::/:/g; # restore <>:'
그리고 perl
:
perl -pe's|START.*?END|$&=~y/\\"//rd|ge'
답변4
당신은댓글로 지적해이것도 awk
허용됩니다. 그래서 내 대답은 그것에 근거합니다.
START
s와 s가 균형을 이룬다고 가정하고 END
두 단어 중 한 줄을 분할하면 모든 짝수 필드에서 백슬래시와 큰따옴표를 제거하려는 경우가 발생합니다. 이를 위해:
awk -F 'START|END' '{
for(i=2;i<=NF;i+=2){ # For each even-numbered field
gsub(/["\\]/,"",$i) # Remove " and \ from it
$i="START"$i"END" # Put START and END back around it
}
}' your_file
이는 귀하의 구현에 제가 보장할 수 없는 기능이 awk
있다고 가정합니다.gsub
참고로 기본적으로 " 줄 일치로 시작하고 끝나는 줄 범위 sed
에 대체 적용 "이라고 표시되어 있으므로 작동하지 않습니다.START
END