터미널 사용 : 정규식 사용 II : 대체

나 자신에 이전 기사 정규식에서 가장 많이 사용되는 각 특수 문자가 어떻게 작동하는지 기본 수준에서 설명했습니다. 이러한 정규식을 사용하면 텍스트 파일이나 다른 명령의 출력에서 ​​복잡한 검색을 수행 할 수 있습니다. 이 기사에서는 단순히 한 텍스트를 다른 텍스트로 변경하는 것보다 훨씬 더 강력한 방법으로 sed 명령을 사용하여 텍스트를 찾고 바꾸는 방법을 설명합니다.

grep 명령에 대해 조금 더

sed에 대해 이야기하기 전에 이전 기사에서 설명했던 내용을 완료하기 위해 grep 명령에 대해 좀 더 설명하고 싶습니다. 내가 말하려는 모든 것은 이것과도 관련이 있습니다. 나중에 우리는 이것과 검색 사이의 관계를 볼 것입니다.

정규식 결합

이전 기사에서 언급 한 많은 특수 문자는 다른 문자뿐만 아니라 전체 정규 표현식과 결합 될 수 있습니다. 이를 수행하는 방법은 괄호를 사용하여 하위 표현식을 형성하는 것입니다. 이것의 예를 봅시다. 테스트에 사용할 수있는 텍스트를 다운로드하여 시작하겠습니다. 구문 목록입니다. 이를 위해 다음 명령을 사용합니다.

curl http://artigoo.com/lista-de-frases-comparativas-comicas 2>/dev/null | sed -n 's/.*\(.*\.\)<\/p>/\1/gp' > frases

 그러면«phrases»라는 파일을 실행하는 디렉토리에 남게됩니다. 열어보고 약간 웃을 수 있습니다. 🙂

이제 정확히 6 개의 단어가있는 구를 찾고 싶다고 가정 해 보겠습니다. 어려움은 각 단어와 일치하는 정규식을 형성하는 것입니다. 단어는 대문자 또는 소문자로 된 일련의 문자로, 다음과 같습니다. '[a-zA-Z]+', 그러나 이러한 문자는 문자가 아닌 다른 문자로 구분해야 함을 지정해야합니다. 즉, '[a-zA-Z]+[^a-zA-Z]+'. 기억하십시오. 대괄호 안의 첫 번째 문자 인 "^"는 범위에없는 문자와 일치 시키려고 함을 나타내고 "+"는 1 개 이상의 문자를 나타냅니다.

단어와 일치 할 수있는 정규식이 이미 있습니다. 6과 페어링하려면 6 번 반복해야합니다. 이를 위해 우리는 키를 사용했지만 두는 것은 쓸모가 없습니다. '[a-zA-Z]+[^a-zA-Z]+{6}', 6은 정규 표현식의 마지막 부분을 반복하고 우리가 원하는 것은 모든 것을 반복하는 것이므로 우리가 넣어야 할 것은 다음과 같습니다. '([a-zA-Z]+[^a-zA-Z]+){6}'. 괄호로 하위 표현식을 만들고 중괄호로 6 번 반복합니다. 이제 전체 줄을 일치시키기 위해 앞에 "^"를 추가하고 뒤에 "$"를 추가하면됩니다. 명령은 다음과 같습니다.

grep -E '^([a-zA-Z]+[^a-zA-Z]+){6}$' frases

결과는 우리가 원했던 것입니다.

Macarena보다 더 많이 노래합니다. 당신은 루이스 아 길레보다 더 끝났습니다. 당신은 돌보다 문화가 적습니다. Cañita Brava보다 더 많은 언어를 알고 있습니다. 그는 Tutan Khamón보다 주름이 더 많습니다. 당신은 보육에 대해 람보보다 덜 알고 있습니다.

확장 정규식을 사용하여 "+"가 작동하도록하기 위해 -E 매개 변수를 넣었습니다. 기본을 사용했다면 괄호와 중괄호를 피해야합니다.

역 참조 또는 역 참조

맞춤법 검사기가 설치되어있는 경우 다음 단어 목록이있을 것입니다. /usr/share/dict/words. 그렇지 않은 경우 다음을 사용하여 아치에 설치할 수 있습니다.

sudo pacman -S words

또는 데비안에서 :

sudo aptitude install dictionaries-common

원하는 경우 파일을 살펴보고 어떤 단어가 있는지 확인할 수 있습니다. 실제로 배포판이 사용되는 언어의 단어 파일에 대한 링크입니다. 동시에 여러 단어 파일을 설치할 수 있습니다.

우리는 그 파일을 사용할 것입니다. 우리는 거기에있는 일곱 글자 회문을 모두 알고있는 것이 매우 궁금합니다. 모르는 사람들을 위해 : 회문은 capicúa 단어입니다. 즉, 왼쪽에서 오른쪽으로, 그리고 오른쪽에서 왼쪽으로 읽을 수 있습니다. 다음 명령을 시도해 보겠습니다.

grep '^\(.\)\(.\)\(.\).\3\2\1$' /usr/share/dict/words

좀 이상해 보이죠? 시도해 보면 결과는 배포판의 언어와 목록의 단어에 따라 다르지만 제 경우에는 스페인어를 사용하면 결과는 다음과 같습니다.

아닐린 아닐린 롤링

이 정규식이 어떻게 작동하는지 봅시다.

우리가 이미 그것이 무엇인지 알고있는 "^"와 "$"를 제외하고, 왼쪽에서 가장 먼저 보게되는 것은 괄호로 묶인 세 그룹의 점입니다. 각 괄호 앞의 막대로 혼동하지 마십시오. 기본 정규식을 사용하고 있기 때문에 괄호를 이스케이프해야하지만 다른 의미는 없습니다. 중요한 점은 점이있는 XNUMX 개의 문자를 요구하지만 각 점은 괄호로 묶여 있다는 것입니다. 이는 정규 표현식에서 다시 참조 할 수 있도록 해당 포인트와 일치하는 문자를 저장하는 것입니다. 이것은 나중에 대체 할 때 유용하게 사용할 괄호의 또 다른 사용입니다.

여기에서 아래의 세 숫자 앞에 슬래시가 있습니다. 이 경우 막대가 중요합니다. 아래 번호가 역 참조이고 이전 괄호 중 하나를 참조하고 있음을 나타내는 데 사용됩니다. 예 : \ 1은 첫 번째 괄호를, \ 2는 두 번째 괄호를 나타냅니다.

즉, 우리가 입력 한 정규식에서 우리가 찾고있는 것은 XNUMX 개의 문자로 시작하고 세 번째와 동일한 문자를 갖는 모든 단어입니다. 그것은 첫 번째와 동일합니다. 결과는 단어 목록에있는 XNUMX 자 회문입니다. 우리가 원했던대로.

확장 정규식을 사용하는 경우 괄호를 이스케이프 할 필요는 없지만 확장 정규식을 사용하면 역 참조가 표준화되지 않았기 때문에 모든 프로그램에서 작동하지 않습니다. 그러나 grep을 사용하면 작동하므로 동일한 작업을 수행하는 또 다른 방법이 될 수 있습니다. 원한다면 시도해 볼 수 있습니다.

대체 표현식 : sed 명령

검색 외에도 정규식의 가장 좋은 용도 중 하나는 복잡한 텍스트를 대체하는 것입니다. 이를 수행하는 한 가지 방법은 sed 명령을 사용하는 것입니다. sed 명령의 힘은 텍스트를 대체하는 것 이상의 의미가 있지만 여기서는이를 위해 사용하겠습니다. 이 명령에 사용할 구문은 다음과 같습니다.

sed [-r] 's/REGEX/REPL/g' FICHERO

또는 :

COMANDO | sed [-r] 's/REGEX/REPL/g'

여기서 REGEX는 검색 정규식이고 REPL은 대체 정규식입니다. 이 명령은 우리가 표시하는 파일의 어떤 것도 실제로 대체하지는 않지만 터미널에서 대체 결과를 보여주는 것이므로 다음에 입력 할 명령에 대해 두려워하지 마십시오. 그들 중 어느 것도 시스템의 파일을 수정하지 않습니다.

간단한 예부터 시작하겠습니다. 우리 모두는 일반적으로 "#"로 시작하는 주석이있는 / etc 디렉토리에 다양한 구성 파일을 가지고 있습니다. 주석없이 이러한 파일 중 하나를보고 싶다고 가정합니다. 예를 들어, fstab으로 할 것입니다. 당신이 원하는 것을 시도 할 수 있습니다.

sed 's/#.*//g' /etc/fstab

fstab에있는 내용에 따라 다르기 때문에 여기에 명령의 결과를 넣지 않겠습니다. 그러나 명령의 출력을 파일의 내용과 비교하면 모든 주석이 사라진 것을 알 수 있습니다.

이 명령에서 검색 표현식은«#.*", 그건"# "뒤에 임의의 수의 문자, 즉 주석이옵니다. 그리고 대체 표현식은 연속 된 두 개의 막대를 보면 아무것도 없다는 것을 알 수 있습니다. 그래서 그것이하는 일은 주석을 아무것도 바꾸지 않는 것, 즉 삭제하는 것입니다. 불가능합니다.

이제 우리는 반대로 할 것입니다. 우리가 원하는 것은 파일의 모든 줄을 주석 처리하는 것입니다. 다음과 같이 해보자 :

sed 's/^/# /g' /etc/fstab

명령 출력에서 ​​모든 행이 해시 표시와 공백으로 시작하는 것을 볼 수 있습니다. 우리가 한 일은 줄의 시작 부분을«# «. 이것은 또한 대체 할 텍스트가 항상 동일한 매우 간단한 예이지만 이제는 좀 더 복잡하게 만들 것입니다.

대체의 은총은 대체 표현식에서 이전에 말한 것과 같은 역 참조를 사용할 수 있다는 것입니다. 기사의 시작 부분에서 다운로드 한 구문 파일로 돌아가 보겠습니다. 우리는있는 모든 대문자를 괄호로 묶을 것입니다. 그러나 우리는 그것을 명령으로 할 것입니다 :

sed 's/\([A-Z]\)/(\1)/g' frases

여기에있는 것은 검색 표현식의 괄호를 참조하는 대체 표현식의 역 참조입니다. 대체 표현식의 괄호는 일반 괄호입니다. 대체 표현에서는 특별한 의미가 없으며있는 그대로 둡니다. 결과적으로 모든 대문자는 괄호로 둘러싼 동일한 문자로 대체됩니다.

대체 표현식에도 사용할 수있는 다른 문자가 있습니다. "&"이며 검색 표현식과 일치하는 모든 텍스트로 대체됩니다. 이에 대한 예는 파일의 모든 구문을 따옴표로 묶는 것입니다. 다음 명령으로 수행 할 수 있습니다.

sed 's/.*/"&"/g' frases

이 명령의 작동은 이전 명령과 매우 유사합니다. 이제 우리가 대체하는 것은 전체 줄을 따옴표로 묶은 동일한 줄입니다. "&"를 사용하고 있으므로 괄호를 넣을 필요가 없습니다.

정규식이있는 유용한 명령

다음은 유용하거나 호기심이 많고 정규 표현식을 사용하는 몇 가지 명령입니다. 이 명령을 사용하면 정규식의 유용성이 지금까지 제공 한 예제보다 훨씬 낫지 만 정규식을 이해하기 위해 어떻게 작동하는지 설명하는 것이 중요해 보였습니다.

  • 매뉴얼 페이지의 섹션을 표시합니다.

man bash | grep '^[A-Z][A-Z ]*$'

물론 bash 명령을 원하는대로 변경할 수 있습니다. 그런 다음 man에서 물론 정규 표현식을 사용하여 관심있는 섹션으로 직접 이동할 수 있습니다. «/»를 눌러 검색을 시작하고«^ALIASES$»예를 들어 ALIASES 섹션으로 이동합니다. 몇 년 전에 정규 표현식을 처음 사용하기 시작한 것 같습니다. 이와 같은 속임수없이 매뉴얼의 일부 페이지를 이동하는 것은 거의 불가능합니다.

  • 특수한 사용자를 포함하여 시스템의 모든 사용자 이름을 표시합니다.

sed 's/\([^:]*\).*/\1/' /etc/passwd

  • 사용자 이름을 표시하지만 셸이있는 이름 만 표시합니다.

grep -vE '(/false|/nologin)$' /etc/passwd | sed 's/\([^:]*\).*/\1/g'

단일 정규식으로 실제로 수행 할 수 있지만이를 수행하는 방법은이 기사에서 말한 것 이상이므로 두 명령을 결합하여 수행했습니다.

  • 숫자 파일에있는 모든 숫자의 마지막 세 자리 앞에 쉼표를 삽입합니다.

sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers

최대 6 자리 숫자로만 작동하지만 XNUMX 자리 숫자의 다른 그룹에 구분 기호를 배치하기 위해 두 번 이상 호출 할 수 있습니다.

  •  파일에서 모든 이메일 주소를 추출합니다.

grep -E '\<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\>' FICHERO

  • 파일에 나타나는 모든 날짜의 일, 월 및 연도를 구분하십시오.

sed -r 's/([0-9]{2})[/-]([0-9]{2})[/-]([0-9]{4})/Día: \1, Mes: \2, Año: \3/g' FICHERO

  • 로컬 IP를 찾으십시오.

/sbin/ifconfig | grep 'inet .*broadcast' | sed -r 's/[^0-9]*(([0-9]+\.){3}[0-9]+).*/\1/g'

이것은 단일 sed 명령으로도 수행 할 수 있지만 단순성을 위해 grep과 sed로 분리하는 것이 좋습니다.

유용한 주소

다음은 정규 표현식과 관련하여 유용 할 수있는 몇 가지 주소입니다.

  • 정규식 라이브러리: 관심있는 주제와 관련된 정규식을 검색 할 수있는 정규식 라이브러리입니다. 웹 주소, ID 등을 검색합니다.
  • RegExr: 온라인 정규식 검사기. 텍스트를 입력하고 검색 또는 대체에 정규식을 적용 할 수 있습니다. 정규식에 대한 정보를 제공하며 동작을 변경할 수있는 몇 가지 옵션이 있습니다.
  • 정규식 테스터: 브라우저에서 정규식을 확인할 수있는 Firefox 용 애드온입니다.

결론

지금은 그게 다입니다. 정규식은 복잡하지만 유용합니다. 배우는 데는 시간이 걸리지 만 나와 같다면 가지고 노는 것이 재미있어 보이고 조금씩 마스터하게 될 것입니다. 그것은 전 세계입니다. 게으른 수량 자, PERL 스타일 정규식, 여러 줄 등에 대해 아직 할 말이 많이있을 것입니다. 그리고 각 프로그램에는 특성과 변형이 있으므로 제가 드릴 수있는 최선의 조언은 항상 새 프로그램에서 정규식을 작성해야 할 때마다 사용중인 프로그램의 문서를 살펴 보는 것입니다.

야! …야! … 일어나! … 여러분은 모두 무엇을 잤습니까? 🙂

소스

여기에서 가져온이 기사의 정규식에 대한 몇 가지 아이디어와 예제는 다음과 같습니다.


15 코멘트, 당신의 것을 남겨주세요

코멘트를 남겨주세요

귀하의 이메일 주소는 공개되지 않습니다. 필수 필드가 표시되어 있습니다 *

*

*

  1. 데이터 책임자 : Miguel Ángel Gatón
  2. 데이터의 목적 : 스팸 제어, 댓글 관리.
  3. 합법성 : 귀하의 동의
  4. 데이터 전달 : 법적 의무에 의한 경우를 제외하고 데이터는 제 XNUMX 자에게 전달되지 않습니다.
  5. 데이터 저장소 : Occentus Networks (EU)에서 호스팅하는 데이터베이스
  6. 권리 : 귀하는 언제든지 귀하의 정보를 제한, 복구 및 삭제할 수 있습니다.

  1.   엘라 브

    대가 다운!!!

    1.    Hexborg

      그렇게 나쁘지는 않지만 대단히 감사합니다. 사람들이 좋아하기를 바랍니다. 🙂

      1.    오스카

        나는 그것을 좋아한다!

        1.    Hexborg

          그럼 내가 옳은 일을 한 게 틀림 없어. LOL !! 🙂

          귀하의 의견에 감사드립니다.

          1.    블레어 파스칼

            좆까 계속 쓰는 사람, 계속해.

          2.    Hexborg

            @Blaire Pascal : 귀하의 의견이이를 권장합니다. 🙂 대단히 감사합니다 !!

      2.    시툭스

        나는 또한 그것을 좋아했다 ... 고마워 🙂

        1.    Hexborg

          의견 감사합니다. 몇 가지 더 쓰고 싶습니다. 🙂

  2.   마리안

    귀하의 게시물은 환상적이며 많은 것을 배우는 대신 우아하고 효율적인 방식으로 작업을 수행하는 방법을 배웁니다.

    모든 쉘 스크립트 게시물을 수집하는 것에 대해 생각해 보셨습니까? pdf로 분류하면 훌륭한 매뉴얼이 될 것입니다.

    힘내고 대단히 감사합니다!

    1.    Hexborg

      감사합니다 !! 나쁜 생각이 아닙니다. 지금은 두 개 밖에 없지만 나중에 생각해 보겠습니다. 🙂

  3.   키요 프

    아주 좋은 기사, 5+.

    1.    Hexborg

      감사합니다. 당신이 그것을 좋아해서 기쁩니다. 🙂

  4.   바스 챤

    우수한! 다음 식을 변경해야하는데 어떻게해야하는지 모르겠습니다.
    192.168.0.138/Server 기준 192.168.0.111/data
    문제는 "/"기호에 있습니다.
    다음 명령을 사용하고 있습니다.
    찾기. -name "* .txt"-exec sed -i 's / TEXT1 / TEXT2 / g'{} \;
    이 유형의 작업을 거부 적으로 수행하는 데 사용되는 것은 무엇입니까?
    내가 어떻게해야하는지 아는 사람 있나요?
    안아!
    세바

    1.    Hexborg

      당신이해야 할 일은 다음과 같이 캐릭터를 이스케이프하는 것입니다.

      찾기. -name "* .txt"-exec sed -i 's / \ / 서버 / \ / 데이터 / g'{} \;

      sed에서 다른 구분 기호를 사용할 수도 있습니다. 바일 필요는 없습니다. Sed는 모든 문자를 사용할 수 있습니다. 예를 들어, 이것은 더 명확합니다.

      찾기. -name "* .txt"-exec sed -i 's | / Server | / data | g'{} \;

      그리고이 주석에서 명령을 복사하여 붙여 넣으려면 따옴표에주의하십시오. 워드 프레스는 인쇄용 명령을 변경합니다. 🙂

      인사말.

  5.   바스 챤

    우수한!!!!
    저는이 솔루션을 오랫동안 찾고있었습니다.
    여기에 내가 사용한 완전한 명령을 남깁니다.

    찾기. -name "* .txt"-exec sed -i 's | 192 \ .168 \ .0 \ .238 \ / 서버 | 192 \ .168 \ .0 \ .111 \ / data | g'{} \;

    이 명령의 장점은 모든 .txt 파일 (또는 원하는 확장명)을 재귀 적으로 변경한다는 것입니다 ... 매우 조심해야합니다!
    그러나 그것은 매우 유용합니다 !!!

    글쎄, 모든 것에 감사하고 전체 그룹에 천 번 축하합니다.
    나는 항상 메일에서 그들을 읽습니다!
    포옹
    세바