태그 보관물: shell

shell

\\를 사용한 정규 표현식과 \를 사용한 정규 표현식 네 번째

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\,(쉼표) 및 -ogrep 옵션을 추가하여 일치하는 부분 만 인쇄 하여 예제를 약간 수정 해 봅시다 .

  • 다음과 같은 경우 .모든 문자와 일치합니다 ( ''주변의 알림 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\\\\.\\\\ggrep 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 \\\\: \\— 특수 조합, 특수 조합

echobash해석 후 결과 문자열을 인쇄합니다 . 추가 정보 : bash 문서 , bash 해커 위키 , POSIX 사양 .

.에 특별한 의미가 없습니다 bash. 쉘의 일반적인 특성입니다. 아래는 귀하의 예와 관련된 순서입니다.

  • echo .: .
  • echo \.: .
  • echo \\.: \.
  • echo \\\.: \.
  • echo \\\\.: \\.

bash의 리터럴 문자열에 대한 간단한 솔루션

문자 그대로 매개 변수를 전달하려면 bash작은 따옴표 '이스케이프를 사용할 수 있습니다 . 작은 따옴표 사이에서 작은 따옴표는 특별한 의미를 가진 유일한 문자이므로 문자의 특수 의미에 신경 쓸 필요가 없습니다. 문자열의 첫 부분을 묶은 후 작은 따옴표를 삽입 할 수 있습니다. 예 :
echo 'part1'\''part2': part1'part2

grep의 정규식

\에서와 비슷한 의미를 가진 이스케이프 문자입니다 bash. 모든 문자의 단일 발생.나타내는 특수 문자입니다 . POSIX regex , GNU grep regex를 참조하십시오 . 정규식의 예 :

  • .a또는 같은 문자를 찾습니다.
  • \..말 그대로 만 일치

당신의 예

아래의 모든 예제의 두 번째 줄에는 '어떤 리터럴 문자열이 전달되는지를 나타내는 작은 따옴표 bashgrep있습니다. 그런 다음 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.

답변