다음 스크립트를 보자.
#!/bin/sh
sed 's/(127\.0\.1\.1)\s/\1/' [some file]
sh
( dash
here)에서 이것을 실행하려고 하면 괄호로 인해 실패해야하며 탈출해야합니다. 그러나 백 슬래시 자체를 피할 필요 는 없습니다 (옥텟 사이 \s
또는 또는 \1
). 여기서 규칙은 무엇입니까? {...}
또는 [...]
언제 사용해야 합니까? 내가하고 도망 칠 필요가없는 목록이 있습니까?
다음 스크립트를 보자.
#!/bin/sh
sed 's/(127\.0\.1\.1)\s/\1/' [some file]
sh
( dash
here)에서 이것을 실행하려고 하면 괄호로 인해 실패해야하며 탈출해야합니다. 그러나 백 슬래시 자체를 피할 필요 는 없습니다 (옥텟 사이 \s
또는 또는 \1
). 여기서 규칙은 무엇입니까? {...}
또는 [...]
언제 사용해야 합니까? 내가하고 도망 칠 필요가없는 목록이 있습니까?
답변:
여기에는 셸과 sed라는 두 가지 수준의 해석이 있습니다.
쉘에서 작은 따옴표 자체를 제외하고 작은 따옴표 사이의 모든 것이 문자 그대로 해석됩니다. 작은 따옴표 사이에 작은 따옴표를 효과적으로 쓸 수 있습니다 '\''
(작은 따옴표, 하나의 리터럴 작은 따옴표, 열린 작은 따옴표).
Sed는 기본 정규 표현식을 사용 합니다 . BRE에서 문자 그대로 처리 $.*[\^
하려면 문자 세트 ( […]
)를 제외하고 문자 앞에 백 슬래시를 사용 하여 문자 를 인용해야합니다 . 문자, 숫자 및 (){}+?|
따옴표로 묶지 말아야합니다 (일부 구현에서 이들 중 일부를 인용하여 벗어날 수 있음). 시퀀스는 \(
, \)
, \n
, 및 일부 구현에서 \{
, \}
, \+
, \?
, \|
등의 백 슬래시 + 알파벳과 숫자는 특별한 의미가 있습니다. $^
일부 구현에서는 일부 위치에서 인용하지 않고 벗어날 수 있습니다 .
또한 /
대괄호 표현식 외부의 정규식에 나타나려면 백 슬래시가 필요합니다 . 예를 들어 s~/dir~/replacement~
또는 \~/dir~p
;를 작성하여 대체 문자를 구분 기호로 선택할 수 있습니다 . BRE에 포함 시키려면 분리 문자 앞에 백 슬래시가 필요합니다. BRE에서 특별한 의미가있는 문자를 선택하고 문자 그대로 포함하려면 세 개의 백 슬래시가 필요합니다. 일부 구현에서는 다르게 동작 할 수 있으므로 권장하지 않습니다.
간단히 말해 sed 's/…/…/'
:
'\''
정규 표현식에서 작은 따옴표로 끝나는 데 사용하십시오 .$.*/[\]^
문자 앞에만 백 슬래시를 넣으십시오 (대괄호 표현식은 제외). (기술적으로 백 슬래시를 넣지 말아야 ]
하지만 대괄호 표현식 외부에서 처리 ]
하고 \]
다르게 구현하는 방법을 모르겠습니다 .)-
문자 그대로 처리하려면 첫 번째 또는 마지막 ( [abc-]
또는 [-abc]
, not [a-bc]
^
문자 그대로 처리 할 수 있는지가되어 있는지 확인 하지 (사용 첫째 [abc^]
,하지 [^abc]
]
브라켓 표현 일치 문자 목록에서, 그것은 (또는 첫 번째 이후의 첫 번째 문자하게 ^
부정 된 세트) []abc]
또는 [^]abc]
(하지 [abc]]
않고[abc\]]
대체 텍스트에서 :
&
및 \
구분 기호 (일반적으로하는 것처럼, 백 슬래시를 앞에 인용 할 필요 /
)와 뉴 라인.\
숫자 다음에 특별한 의미가 있습니다. \
뒤에 나오는 문자는 일부 구현에서 특별한 의미 (특수 문자)를 가지며, \
그 뒤에 다른 문자 수단이 \c
있거나 c
구현에 따라 다릅니다.sed 's/…/…/'
)를 작은 따옴표로 묶으 '\''
면 대체 텍스트에 작은 따옴표를 넣습니다.정규식 또는 대체 텍스트가 쉘 변수에서 온 경우
\n
( sed
패턴 공간에 줄 바꿈 문자를 추가하는 다른 코드 가 없으면 일치하지 않습니다 ). 그러나 일부 sed
구현 에서는 대괄호 표현식에서 작동하지 않습니다 .&
, \
및 줄 바꿈을 인용해야합니다.sed -e "s/$BRE/$REPL/"
.\\*
)를 사용할 수 있습니다 . 예 :echo "***NEW***" | sed /\\*\\*\\*NEW\\*\\*\\*/s/^/#/
겪고있는 문제는 쉘 보간 및 이스케이프 때문이 아닙니다 .sed -r
또는 --regexp-extended
옵션 을 전달하지 않고 확장 정규 표현식 구문을 사용하려고하기 때문 입니다.
sed 라인을 다음에서 변경하십시오.
sed 's/(127\.0\.1\.1)\s/\1/' [some file]
에
sed -r 's/(127\.0\.1\.1)\s/\1/' [some file]
당신이 생각하는대로 작동합니다.
기본적으로 sed는 기본 정규 표현식 (그렙 스타일을 생각합니다)을 사용하며 다음 구문이 필요합니다.
sed 's/\(127\.0\.1\.1\)[ \t]/\1/' [some file]
-r
옵션으로 추가 하는 것이 필자의 경우 필요했습니다.
쉘 변수를 sed 표현식에 보간하지 않으려면 전체 표현식에 작은 따옴표를 사용하십시오. 백 슬래시를 포함하여 변수 사이의 모든 것이 그대로 해석되기 때문입니다.
따라서 sed가 s/\(127\.0\.1\.1\)\s/\1/
그 주위에 작은 따옴표를 붙이고 싶다면 쉘이 괄호 또는 백 슬래시를 만지지 않습니다. 쉘 변수를 보간해야하는 경우 해당 부분 만 큰 따옴표로 묶으십시오. 예 :
sed 's/\(127\.0\.1\.1\)/'"$ip"'/'
이렇게하면 큰 따옴표로 이스케이프되지 않은 쉘 메타 문자를 기억하지 않아도됩니다.
sed
그대로 s/(127\.0\.1\.1)/...
쉘 스크립트에 넣는 것은 작동하지 않습니다. 괄호에 닿지 않는 쉘에 대해 말하는 것은 잘못된 것 같습니다. 정교하게 질문을 편집했습니다.
sed 's/(127\.0\.1\.1)/IP \1/'
나오지도보고해야하기 때문에 실패 \(
및 \)
그룹 구문을하지 않는 (
및 )
.
function sedPath { path=$((echo $1|sed -r 's/([\$\.\*\/\[\\^])/\\\1/g'|sed 's/[]]/\[]]/g')>&1) } #Escape path for use with sed