답변:
먼저 단일 슬래시가 너무 많이 일치합니다.
$ 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
\. \\. \\\. \\\\.
echo
이 경우 bash가 수행 하는 작업을 설명하는 업데이트 된 답변을 참조하십시오 .
\.
또는 .
입니다. bash의 경우 둘 다 동일합니다. 평범한 기간과 같습니다. 따라서 배쉬가 grep에 전달하는 것은 단일 슬래시와 마침표가 모두 동일합니다.
echo
은이 프로그램의 많은 구현으로 인해 정규 표현식을 테스트하는 신뢰할 수있는 방법이 아닙니다. 예를 들어 내 zsh (내장 에코)에서는을 echo \. \\. \\\. \\\\. \\\\\.
제공 . \. \. \. \.
하지만을 /bin/echo \. \\. \\\. \\\\. \\\\\.
반환합니다 . \. \. \\. \\.
. 같은 뭔가가 printf "%s" ...
아마 더 좋은 방법입니다.
출력은 문자열에 대해서만 동일하지만 일반적으로 정규 표현식은 다른 작업을 수행합니다. 두 번째 패턴 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
.
\
다음 문자의 특별한 의미를 취소하는 특수 문자입니다 \
. 다음 문자에 특별한 의미가 없으면 변경없이 전달됩니다. 명령과 결과가있는 예 :
echo \a
: a
— 일반 캐릭터 이스케이프는 캐릭터를 제공합니다echo \\
: \
— 특수 문자 이스케이프는 문자를 제공합니다echo \\\a
: \a
— 특수 조합, 일반echo \\\\
: \\
— 특수 조합, 특수 조합echo
bash
해석 후 결과 문자열을 인쇄합니다 . 추가 정보 : bash 문서 , bash 해커 위키 , POSIX 사양 .
.
에 특별한 의미가 없습니다 bash
. 쉘의 일반적인 특성입니다. 아래는 귀하의 예와 관련된 순서입니다.
echo .
: .
echo \.
: .
echo \\.
: \.
echo \\\.
: \.
echo \\\\.
: \\.
문자 그대로 매개 변수를 전달하려면 bash
작은 따옴표 '
이스케이프를 사용할 수 있습니다 . 작은 따옴표 사이에서 작은 따옴표는 특별한 의미를 가진 유일한 문자이므로 문자의 특수 의미에 신경 쓸 필요가 없습니다. 문자열의 첫 부분을 묶은 후 작은 따옴표를 삽입 할 수 있습니다. 예 :
echo 'part1'\''part2'
: part1'part2
\
에서와 비슷한 의미를 가진 이스케이프 문자입니다 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.
\\\.
grep을 가져다 줄 것이라고 생각\.
했지만 그렇지 않습니다. 좋은 질문