최근에 명령 줄에서 일부 정규 표현식에 문제가 있었고 백 슬래시를 일치시키기 위해 다른 수의 문자를 사용할 수 있음을 발견했습니다. 이 숫자는 정규식에 사용 된 따옴표 (없음, 작은 따옴표, 큰 따옴표)에 따라 다릅니다. 의미하는 바는 다음 bash 세션을 참조하십시오.
echo "#ab\\cd" > file
grep -E ab\cd file
grep -E ab\\cd file
grep -E ab\\\cd file
grep -E ab\\\\cd file
#ab\cd
grep -E ab\\\\\cd file
#ab\cd
grep -E ab\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\\cd file
grep -E "ab\cd" file
grep -E "ab\\cd" file
grep -E "ab\\\cd" file
#ab\cd
grep -E "ab\\\\cd" file
#ab\cd
grep -E "ab\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\\cd" file
grep -E 'ab\cd' file
grep -E 'ab\\cd' file
#ab\cd
grep -E 'ab\\\cd' file
#ab\cd
grep -E 'ab\\\\cd' file
이것은 다음을 의미합니다.
- 따옴표없이 4-7 실제 백 슬래시와 백 슬래시를 일치시킬 수 있습니다
- 큰 따옴표로 백 슬래시를 3-6 실제 백 슬래시와 일치시킬 수 있습니다
- 작은 따옴표를 사용하면 백 슬래시를 2-3 실제 백 슬래시와 일치시킬 수 있습니다
쉘에서 bash 맨 페이지의 추가 백 슬래시가 무시된다는 것을 이해합니다.
“인용되지 않은 백 슬래시 (\)는 이스케이프 문자입니다. 다음에 오는 다음 문자의 리터럴 값을 유지합니다.”
작은 따옴표로 이스케이프 처리되지 않으므로 작은 따옴표로 묶인 예제에는 적용되지 않습니다.
그리고 grep 명령에 의해 하나의 추가 백 슬래시는 무시됩니다 ( “\ c”는 “c”이스케이프되지만 “c”는 정규식에서 특별한 의미를 갖지 않기 때문에 “c”와 동일합니다)).
이것은 작은 따옴표로 예제의 동작을 설명하지만 다른 두 예제, 특히 qouted가 아닌 큰 따옴표로 묶인 문자열 사이에 차이점이있는 이유를 이해하지 못합니다.
bash 매뉴얼 페이지에서 인용 한 내용은
“큰 따옴표로 문자를 묶으면 $,`, \ 및 히스토리 확장이 활성화 된 경우를 제외하고 따옴표 안에있는 모든 문자의 리터럴 값이 유지됩니다!”
GNU awk (예 :)로 awk /ab\cd/{print} file
동일한 결과를 얻었습니다.
그러나 Perl은 다른 결과를 보여줍니다 (예 🙂 perl -ne
.
"/ab\\cd/"\&\&print file
- 따옴표없이 4-5 실제 백 슬래시와 백 슬래시를 일치시킬 수 있습니다
- 큰 따옴표로 백 슬래시를 3-4 실제 백 슬래시와 일치시킬 수 있습니다
- 작은 따옴표로 백 슬래시를 2 개의 실제 백 슬래시와 일치시킬 수 있습니다
grep과 awk에 대한 명령 줄에서 인용되지 않은 것과 이중 인용 된 정규 표현식 문자열의 차이점을 누구나 설명 할 수 있습니까? 나는 보통 Perl one-liner를 사용하지 않기 때문에 Perl의 행동에 대한 설명에 관심이 없다.
답변
인용되지 않은 예제의 경우, 각 \\
쌍은 하나의 백 슬래시를 grep에 전달하므로 4 개의 백 슬래시는 grep에 전달되어 단일 백 슬래시로 변환됩니다. 6 개의 백 슬래시는 3을 grep으로 전달하여 1 개의 백 슬래시와 1을 변환 \c
합니다 c
. 이 번역되어 있기 때문에 하나의 추가 백 슬래시, 아무것도 변경하지 않는다 \c
> – c
쉘. 쉘의 8 개의 백 슬래시는 grep에서 4 개이며 2 개로 변환되므로 더 이상 일치하지 않습니다.
큰 따옴표로 묶인 예를 보려면 bash 맨 페이지에서 두 번째 따옴표 뒤에 나오는 내용을 참고하십시오.
백 슬래시는 $,`, “, \ 또는 개행 문자 중 하나가 뒤에 오는 경우에만 특별한 의미를 유지합니다.
즉, 홀수의 백 슬래시를 제공하면 순서는로 끝나고 인용되지 않은 경우와 \c
동일 c
하지만 인용하면 백 슬래시는 특별한 의미 \c
를 잃어 grep으로 전달됩니다. 따라서 “가능한”백 슬래시 범위 (예 : 파일과 일치하는 패턴을 구성하는 백 슬래시)의 범위가 하나씩 아래로 내려갑니다.
답변
이 링크는 bash 따옴표와 이스케이프를 설명했습니다.
귀하의 질문은 처음 세 섹션을 다룹니다.
- 문자 별 이스케이프
- “큰 따옴표”를 인용하는 약한
- 강력한 인용문 ‘작은 따옴표’
- 문자열 인용과 같은 ANSI C
- I18N / L10N 인용 (국제화 및 현지화) .
아래는 문자열을 bash
전달하는 grep
방법과 grep
내부적으로 더 해석하는 방법 에 대한 차트입니다 .
먼저 살펴 보자 echo "#ab\\cd" > file
.
(가)에서 약 인용 ( “”) "#ab\\cd"
, (가) \\
인 탈출 \
에 전달되는 file
하나의 문자로 \
. 그래서, file
포함 ab\cd
이제 여러분의 명령에 따라 : 아래 차트는 각 통화에서 실제로 어떤 일이 진행되는지 확인하는 데 도움이 될 수 있습니다. 는 *
파일의 내용과 일치하는 사람을 보여줍니다. 웹 페이지에서와 같이 bash의 이스케이프 규칙을 적용하는 것은 문제입니다. 다니엘 쿨만 (Daniel Kullmann)의 대답은 약한 인용 상황 에서 행동을 피하는 것을 말합니다 .
백 슬래시는 $,`, “, \ 또는 개행 문자 중 하나가 뒤에 오는 경우에만 특별한 의미를 유지합니다.
bash passes grep further
to grep resolves to
grep -E ab\cd file abcd abcd
grep -E ab\\cd file ab\cd abcd
grep -E ab\\\cd file ab\cd abcd
grep -E ab\\\\cd file ab\\cd ab\cd *
grep -E ab\\\\\cd file ab\\\cd ab\cd *
grep -E ab\\\\\\cd file ab\\\cd ab\cd *
grep -E ab\\\\\\\cd file ab\\\cd ab\cd *
grep -E ab\\\\\\\\cd file ab\\\\cd ab\\cd
grep -E "ab\cd" file ab\cd abcd
grep -E "ab\\cd" file ab\cd abcd
grep -E "ab\\\cd" file ab\\cd ab\cd *
grep -E "ab\\\\cd" file ab\\cd ab\cd *
grep -E "ab\\\\\cd" file ab\\\cd ab\cd *
grep -E "ab\\\\\\cd" file ab\\\cd ab\cd *
grep -E "ab\\\\\\\cd" file ab\\\\cd ab\\cd
grep -E 'ab\cd' file ab\cd abcd
grep -E 'ab\\cd' file ab\\cd ab\cd *
grep -E 'ab\\\cd' file ab\\\cd ab\cd *
grep -E 'ab\\\\cd' file ab\\\\cd ab\\cd