sed
다음과 같은 간단한 예제를 통해 재현할 수 있는 문제가 있습니다 .
다음 입력 파일을 고려하십시오(입력.txt):
C:\A\quick\brown\fox\ jumps over the lazy dog
C:\A\quick\brown\fox\ ran with the hounds
다음 출력을 생성하고 싶습니다
C:\Animal\ jumps over the lazy dog
C:\Animal\ ran with the hounds
sed를 사용하여 간단한 쉘 스크립트를 작성하려고 시도했지만 필요한 대체 작업을 수행하지 못했습니다. 이것은 내 스크립트입니다.
FROM_PATTERN="C:\A\quick\brown\fox\"
TO_PATTERN="C:\Animal\"
#FROM_PATTERN="C:\\A\\quick\\brown\\fox\\" # Escaping backslash does not help either
#TO_PATTERN="C:\\Animal\\" # Escaping backslash does not help either
sed 's/$FROM_PATTERN/$TO_PATTERN/g' input.txt
#sed 's/"$FROM_PATTERN"/"$TO_PATTERN"/g' input.txt # Quoting the pattern does not help either
제가 쓰고 있는 bash
버전GNU bash, version 4.4.12(3)-release-(x86_64-unknown-cygwin)
답변1
\
아주 특별한:
- 내부 큰따옴표를 포함하여 쉘의 인용 연산자로 자체를 이스케이프하고 줄 연속을 수행하는 데 사용할
"
수$
있습니다`
. s
에 있는 정규식 연산자(이스케이프 및 새 연산자 도입에 사용됨)sed
.- command 의 대체 부분에서 , 자체 및 개행 문자를
s
sed
이스케이프할 수 있습니다 (또는 일부 구현에서 C 스타일 이스케이프 시퀀스를 도입함).&
\n
sed
또한 작은따옴표로 묶인 문자열 내에서는 쉘 매개변수 확장이 수행되지 않습니다.
여기에서 원하는 것은 다음과 같습니다.
\
문자 주위에는 큰따옴표 대신 작은따옴표를 사용하세요.- 명령
\
의 왼쪽과 오른쪽을 탈출하세요s
- 확장해야 하는 변수 부분을 큰따옴표로 묶습니다.
from_regexp='C:\\A\\quick\\brown\\fox\\'
escaped_replacement='C:\\Animal\\'
sed "s/$from_regexp/$escaped_replacement/g" < your-file
또는 다음과 같이 특수 문자에 대해 걱정하지 않고 고정 문자열을 바꿀 수 있는 perl
경우 대신 사용할 수 있습니다 .sed
from='C:\A\quick\brown\fox\'
to='C:\Animal\'
FROM=$from TO=$to perl -pe 's/\Q$ENV{FROM}\E/$ENV{TO}/g' < your-file
당신은 또한 볼 수 있습니다"sed" 대체에 삽입된 문자열이 모든 메타 문자를 이스케이프하는지 확인하는 방법임의의 문자열을 처리합니다.
답변2
이것은 Linux 시스템에서 실행되었지만 cygwin이 Linux의 bash와 동일하게 작동하는지 확실하지 않습니다.
PC1:~> echo 'C:\A\quick\brown\fox\ jumps over the lazy dog' | sed -ne 's|\(C:\\A\).\+\\\+\(.\+\)|\1nimal\2|p'
C:\Animal jumps over the lazy dog
PC1:~> echo 'C:\A\quick\brown\fox\ ran with the hounds' | sed -ne 's|\(C:\\A\).\+\\\+\(.\+\)|\1nimal\2|p'
C:\Animal ran with the hounds
PC1:~>
그래서 그룹 캡처를 사용하여 "A"를 반복한 다음 그 뒤에 "nimal"을 추가했습니다. 좀 더 명확하게 하기 위해 슬래시를 너무 많이 사용하지 않도록 대체 구분 기호로 "|"를 사용했습니다.
도움이 되었기를 바랍니다.