왜
grep e\\.g\\. <<< "this is an e.g. wow"
과
grep e\.g\. <<< "this is an e.g. wow"
같은 일을합니까?
세 번째 슬래시를 추가하면 동일한 결과가 나타납니다. 그러나 네 번째 슬래시를 추가하면 더 이상 작동하지 않습니다. 이것은 수업에 대한 오래된 시험의 질문과 관련이 있습니다. 백 슬래시가 2 개있는 줄이 “eg”로 줄을 출력 할 수 있는지 물었습니다. 원래는 작동하지 않는다고 생각했지만 확인하려고했습니다. 설명은 무엇입니까?
답변
먼저 단일 슬래시가 너무 많이 일치합니다.
$ echo $'eegg \n e.g.' | grep e\.g\.
eegg
e.g.
지금까지로 강타가 우려, 이스케이프 기간은 기간과 동일합니다. 배쉬는 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은 원하는대로 마침표 앞에 슬래시가 표시됩니다.
슬래시가 4 개인 경우 Bash는 각 쌍을 단일 슬래시로 줄입니다. 배시는 두 개의 슬래시와 마침표를 그 리핑합니다. grep은 두 개의 슬래시와 마침표를보고 두 개의 슬래시를 단일 문자 슬래시로 줄입니다. 입력에 문자 뒤에 슬래시가 있고 문자가 없으면 일치 항목이 없습니다.
마지막으로 설명하기 위해 작은 따옴표 안에는 모든 문자가 리터럴이라는 것을 기억하십시오. 따라서 다음 세 개의 입력 행이 주어지면 grep 명령은 입력에서 리터럴 슬래시가있는 행에서만 일치합니다.
$ echo 'eegg
e.g.
e\.g\.' | grep e\\\\.g\\\\.
e\.g\.
배쉬의 행동 요약
Bash의 경우 규칙은
-
두 개의 슬래시는 단일 슬래시로 줄어 듭니다.
-
마침표와 같은 일반 문자 앞의 슬래시는 단지 일반 문자 (마침표)입니다.
그러므로:
$ echo \. \\. \\\. \\\\.
. \. \. \\.
이 모든 혼란을 피하는 간단한 방법이 있습니다. Bash 명령 행에서 정규식은 작은 따옴표로 묶어야합니다. 작은 따옴표 안에 Bash는 모든 것을 내버려 둡니다.
$ echo '\. \\. \\\. \\\\.' # Note single-quotes
\. \\. \\\. \\\\.
답변
출력은 문자열에 대해서만 동일하지만 일반적으로 정규 표현식은 다른 작업을 수행합니다. 두 번째 패턴 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,
-
다음
.
으로 backslash로 이스케이프 처리\
하므로 리터럴 만.
일치합니다.$ 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\.
''
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)
답변
을 수행 grep e\.g\.
하면 셸에서 백 슬래시를 소비하므로 grep e.g.
일치 하는을 수행합니다 . 를 할 때 grep e\\.g\\.
, 쉘은 다시 슬래시를 소비하고 있으며 이제는 grep e\.\g.
일치하는를 수행합니다. 이제 쉘에 대한 백 슬래시는 다음과 같습니다 \\
. 따라서, \\
첫 번째는 이스케이프 시퀀스이고 두 번째는 리터럴 백 슬래시입니다. 당신이 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"
)를 사용하십시오.
답변
두 명령은 입력에 대해서만 동일한 출력을 생성하지만 그렇지 않으면 다릅니다. 우리에 무슨 일이 일어나고 있는지 이해하는 데 필요한 매개 변수가 첫번째로 해석하는 방법을 알 필요 bash
가 다음 grep
.
bash에서 탈출
\
다음 문자의 특별한 의미를 취소하는 특수 문자입니다 \
. 다음 문자에 특별한 의미가 없으면 변경없이 전달됩니다. 명령과 결과가있는 예 :
echo \a
:a
— 일반 캐릭터 이스케이프는 캐릭터를 제공합니다echo \\
:\
— 특수 문자 이스케이프는 문자를 제공합니다echo \\\a
:\a
— 특수 조합, 일반echo \\\\
:\\
— 특수 조합, 특수 조합
echo
bash
해석 후 결과 문자열을 인쇄합니다 . 추가 정보 : bash 문서 , bash 해커 위키 , POSIX 사양 .
.
에 특별한 의미가 없습니다 bash
. 쉘의 일반적인 특성입니다. 아래는 귀하의 예와 관련된 순서입니다.
echo .
:.
echo \.
:.
echo \\.
:\.
echo \\\.
:\.
echo \\\\.
:\\.
bash의 리터럴 문자열에 대한 간단한 솔루션
문자 그대로 매개 변수를 전달하려면 bash
작은 따옴표 '
이스케이프를 사용할 수 있습니다 . 작은 따옴표 사이에서 작은 따옴표는 특별한 의미를 가진 유일한 문자이므로 문자의 특수 의미에 신경 쓸 필요가 없습니다. 문자열의 첫 부분을 묶은 후 작은 따옴표를 삽입 할 수 있습니다. 예 :
echo 'part1'\''part2'
: part1'part2
grep의 정규식
\
에서와 비슷한 의미를 가진 이스케이프 문자입니다 bash
. 모든 문자의 단일 발생.
을 나타내는 특수 문자입니다 . POSIX regex , GNU grep regex를 참조하십시오 . 정규식의 예 :
.
—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.