왜
grep e\\.g\\. <<< "this is an e.g. wow"
그리고
grep e\.g\. <<< "this is an e.g. wow"
같은 일을 합니까?
세 번째 슬래시를 추가하면 동일한 결과를 얻습니다. 그러나 네 번째 슬래시를 추가하자마자 더 이상 작동하지 않습니다. 이것은 이전 과정 시험의 문제와 관련이 있습니다. 두 개의 백슬래시가 있는 항목에 "eg"로 줄을 출력할 수 있는지 묻습니다. 처음에는 작동하지 않는다고 생각했지만 작동하는지 확인하려고 했습니다. 설명은 무엇입니까?
답변1
먼저, 단일 슬래시 일치 항목이 너무 많습니다.
$ echo $'eegg \n e.g.' | grep e\.g\.
eegg
e.g.
한불다이에 관한 도피기간은 형기기간과 동일하다. Bash는 다음으로 기간을 전달합니다.grep. grep의 경우 마침표는 무엇이든 일치할 수 있습니다.
이제 다음을 고려해보세요.
$ echo $'eegg \n e.g.' | grep e\\.g\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\\.g\\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\\\.g\\\\.
$
Bash는 이중 슬래시를 발견하면 이를 단일 슬래시로 줄여서 grep에 전달합니다. 위의 세 가지 테스트 중 첫 번째에서는 예상한 대로 마침표 앞에 단일 슬래시가 표시됩니다. 그러므로 이것이 옳은 일입니다.
삼중 슬래시를 사용하면 Bash는 처음 두 슬래시를 단일 슬래시로 줄입니다. 그러다 그것을 보았다 \.
. 이스케이프된 마침표는 Bash에 특별한 의미가 없으므로 일반 마침표로 단순화됩니다. 그 결과 우리가 바라던 대로 grep이 마침표 앞에 슬래시를 보게 됩니다.
네 개의 슬래시를 사용하면 Bash는 각 슬래시 쌍을 단일 슬래시로 줄입니다. Bash는 grep에 두 개의 슬래시와 마침표를 전달합니다. grep은 두 개의 슬래시와 한 개의 마침표를 보고 두 개의 슬래시를 단일 슬래시로 줄입니다.단어줄이다. 입력에 슬래시 뒤에 문자가 없으면 일치하는 항목이 없습니다.
마지막으로 작은 따옴표 안의 모든 문자는 리터럴이라는 점을 기억하세요. 따라서 다음 세 개의 입력 라인이 있는 경우 grep 명령은 입력에 리터럴 슬래시가 있는 라인만 일치시킵니다.
$ echo 'eegg
e.g.
e\.g\.' | grep e\\\\.g\\\\.
e\.g\.
Bash 동작 요약
Bash의 경우 규칙은 다음과 같습니다.
두 개의 슬래시가 하나의 슬래시로 줄어듭니다.
일반 문자(마침표 등) 앞의 슬래시는 일반 문자(마침표)일 뿐입니다.
그러므로:
$ echo \. \\. \\\. \\\\.
. \. \. \\.
이러한 모든 혼란을 피하는 간단한 방법이 있습니다. Bash 명령줄에서 정규식은 작은따옴표로 묶어야 합니다. 작은 따옴표 내에서 Bash는 모든 것을 유지합니다.
$ echo '\. \\. \\\. \\\\.' # Note single-quotes
\. \\. \\\. \\\\.
답변2
문자열에 대해서만 출력은 동일하지만 일반적으로 이러한 정규식은 다른 작업을 수행합니다. 예제를 약간 수정하여 두 번째 패턴 e,g,
(쉼표 포함), 세 번째 패턴 e\.g\.
(점), 네 번째 패턴 e\,g\,
(쉼표) 및 -o
일치하는 부분만 인쇄하는 grep 옵션을 추가해 보겠습니다.
다음과 같은 경우
.
모든 문자와 일치합니다 (''
주변 환경을 참고하세요e.g.
. 이에 대해서는 나중에 설명하겠습니다).$ grep -o 'e.g.' <<< grep -o 'e.g.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,' e.g. e,g,
다음으로
.
백슬래시 이스케이프를 사용하여\
리터럴만.
일치시킵니다.$ grep -o 'e\.g\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,' e.g.
그러나 리터럴이 다음 (즉, 모든 문자) 과 일치하도록
\
또 다른 이스케이프를 사용할 수 있습니다.\
\
.
$ grep -o 'e\\.g\\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,' e\.g\. e\,g\,
\.
그러나 단지 불일치를\,
원한다면 점\
의 특별한 의미를 벗어나기 위해 또 다른 것이 필요합니다.$ grep -o 'e\\\.g\\\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,' e\.g\.
이제 around grep 매개변수를 사용하지 않기 때문에 ''
쉘 해석에서 백슬래시를 이스케이프 처리하려면 또 다른 백슬래시를 추가해야 합니다.
grep 'e\.g\.' => grep e\\.g\\.
grep 'e\\.g\\.' => grep e\\\\.g\\\\. (each backslash has to be quoted separately)
grep 'e\\\.g\\\.' => grep e\\\\\\.g\\\\\\. (3 x 2 = 6 backslashes in total)
답변3
을 수행하면 grep e\.g\.
쉘이 백슬래시를 사용하므로 grep e.g.
일치하는 을 수행하는 것입니다. 를 실행하면 grep e\\.g\\.
쉘이 슬래시를 다시 사용하고 이제 a를 실행하면 grep e\.\g.
다시 일치합니다. 이제 쉘의 백슬래시는 와 같습니다 \\
. 따라서 가 있을 때 \\
첫 번째는 이스케이프 시퀀스이고 두 번째는 리터럴 백슬래시입니다. 당신이 a를 할 때 리터럴로 만드는 grep e\\\.g\\\.
첫 번째 문자 앞에 이스케이프 시퀀스( )가 없기 때문에 여전히 종료됩니다 . grep e\.\g.
\는 백슬래시이므로 결국에는 분명히 일치하지 않습니다.\
\
\
grep e\\\\.\\\\g
grep e\\.g\\.
쉘이 당신이 하고 있는 일을 어떻게 보는지 보려면 echo를 사용하십시오(예: echo grep e\\.g\\. <<< "this is an e.g. wow"
vs. echo grep e\\\\.g\\\\. <<< "this is an e.g. wow"
).
답변4
이 두 명령은 입력에 대해서만 동일한 출력을 생성하지만 다른 점에서는 다릅니다. 무슨 일이 일어나고 있는지 이해하려면 먼저 매개변수가 어떻게 해석되는지, bash
그 다음에는 어떻게 해석되는지 알아야 합니다 grep
.
배쉬에서 탈출
\
\
후속 문자(자신 포함)의 특별한 의미를 취소하는 특수 문자입니다 . 다음 문자에 특별한 의미가 없으면 변경되지 않고 전달됩니다. 명령 및 결과의 예:
echo \a
:a
— 이스케이프된 일반 문자는 문자를 제공합니다.echo \\
:\
— 특수 문자 이스케이프는 문자를 제공합니다.echo \\\a
:\a
——특별함과 보통함의 결합echo \\\\
:\\
— 조합 특별, 특별
echo
bash
결과 문자열은 해석 후 인쇄됩니다. 추가 정보:배쉬 문서,배쉬 해커 위키,POSIX 사양.
.
특별한 의미는 없습니다 bash
. 쉘의 일반 문자입니다. 귀하의 예와 관련된 순서는 다음과 같습니다.
echo .
:.
echo \.
:.
echo \\.
:\.
echo \\\.
:\.
echo \\\\.
:\\.
Bash의 중국어 텍스트 문자열에 대한 더 간단한 솔루션
매개변수를 문자 그대로 전달하려면 bash
작은따옴표 이스케이프를 사용하면 됩니다 '
. 작은따옴표 사이에서는 작은따옴표만이 특별한 의미를 갖는 문자이므로 문자의 특별한 의미에 대해 신경 쓸 필요가 없습니다. 문자열의 첫 번째 부분을 묶은 후 작은따옴표를 삽입할 수 있습니다. 예:
echo 'part1'\''part2'
: part1'part2
grep의 정규 표현식
\
은 이스케이프 문자이며 그 의미는 와 유사합니다 bash
. .
특수문자다모든 문자의 발생을 나타냅니다.. 바라보다:POSIX 정규식,GNU grep 정규식. 정규식 예:
.
a
— 또는 등의 모든 문자와 일치합니다..
\.
—.
리터럴 일치 만 가능
당신의 모범
아래 각 예의 두 번째 줄에서는 '
어떤 리터럴 문자열이 전달되는지를 나타내는 bash
작은 따옴표가 있는 해당 항목을 찾을 수 있습니다 grep
. 그런 다음 grep
이스케이프를 수행한 후 예제에서 가능한 유일한 특수 문자는 .
임의의 문자와 일치하는 것입니다. 세 번째 줄은 표현식이 일치하는 항목에 대한 설명입니다.
grep e.g. <<< "this is an e.g. wow"
grep 'e.g.' <<< "this is an e.g. wow"
e
모든 문자g
모든 문자—일치e.g.
및 기타 문자열좋다eagb
grep e\.g\. <<< "this is an e.g. wow"
grep 'e.g.' <<< "this is an e.g. wow"
e
모든 문자g
모든 문자—일치e.g.
및 기타 문자열좋다exgy
grep e\\.g\\. <<< "this is an e.g. wow"
grep 'e\.g\.' <<< "this is an e.g. wow"
e.g.
문자 그대로 -e.g.
일치만grep e\\\.g\\\. <<< "this is an e.g. wow"
grep 'e\.g\.' <<< "this is an e.g. wow"
e.g.
문자 그대로 -e.g.
일치만grep e\\\\.g\\\\. <<< "this is an e.g. wow"
grep 'e\\.g\\.' <<< "this is an e.g. wow"
e\
모든 문자g\
모든 문자—불일치e.g.