grep 및 sed의 정규식

grep 및 sed의 정규식

텍스트 파일에서 a로 시작하는 모든 줄을 찾아 바꾸려고 합니다.단일 공간그럼 아무 캐릭터나.

마침내 grep에서 작동하는 정규 표현식을 얻었습니다.grep -E '^ .*$*' Contacts.vcf >> t.txt

그런 다음 sed에서 사용할 때 그렇지 않습니다. sed 's/^ .*$//g' Contacts.vcf > tt.txt(처음의 공백에 관계없이) 모든 줄을 얻습니다. \s{1}다 넣어보려고 했는데 ()실행이 안되네요.

처음 Windows에서 PowerShell을 사용하려고 시도했을 때도 동일한 문제가 발생했습니다. 플랫폼 간 정규식 세부 정보(?)가 누락된 것 같습니다.

정규식에서 단일 공백으로 시작하는 줄만 찾도록 하려면 어떻게 해야 합니까?

답변1

grep"공백으로 시작하고 뒤에 임의의 문자가 옵니다"를 구현하여 단순화할 수 있습니다.

grep '^ .'

"공간으로 시작"하고 싶다면 더 쉽습니다.

grep '^ '

지금 sed다양성모든 것을 입력하고 표시합니다. sed좀 더 유사하게 동작 하려면 플래그와 명령이 grep필요합니다 . 이는 기본적으로 출력을 표시하지 않음을 의미 하며 "이 줄을 인쇄합니다"를 의미합니다.-np-np

예를 들어

sed -n '/^ /p'

마찬가지로 공백으로 시작하는 모든 줄을 표시합니다.

sed -n '/^ ./p'

공백으로 시작하고 그 뒤에 다른 문자가 오는 모든 줄을 표시합니다.

편집하다

다른 의견에 따르면 귀하의 목표는 공백으로 시작하는 줄을 제거하는 것으로 보이며 sed.

이 경우

sed -i '/^ /d'

기본적으로 "공백으로 시작하는 줄을 검색하여 제거"합니다.

예를 들어

$ cat x
hello
 there
everyone

$ sed -i '/^ /d' x

$ cat x
hello
everyone

답변2

공백으로 시작하는 모든 줄을 삭제하려는 경우.

다음 명령과 함께 grep을 사용할 수 있습니다 -v.

grep -v -E '^ .*$' Contacts.vcf > tt.txt

   -v, --invert-match
          Invert the sense of matching, to select non-matching lines.

또한 "$"는 줄의 끝을 나타냅니다.

그 뒤에는 문자가 없어야 합니다.

따라서 "$" 뒤의 별표는 의미가 없습니다.

답변3

당신은 말한다:

단일 공백으로 시작한 다음 임의의 문자로 시작하는 텍스트 파일의 모든 줄을 찾아 바꾸려고 합니다.

나열된 항목에 대한 정규식 구문을 추가하면 다음과 같습니다.

^단일 공백( )으로 시작하고 그 뒤에 임의의 문자(기술적으로 ..*BRE 또는 .+ERE에서는 있지만 1 문자는 "모든 문자"이므로)로 시작 하는 텍스트 파일의 모든 줄을 찾아 바꾸려고 합니다. print 일치하는 특정 문자열을 인쇄하는 대신 일치하는 문자열의 전체 줄을 포함합니다. .정규식만 있으면 됩니다.

그런 다음 이러한 도구의 모든 버전을 사용하여 다음과 같이 직접 구현하십시오.

grep '^ .'
sed -n '/^ ./p'
awk '/^ ./'

부터:

  1. ^= 문자열의 시작 부분(이 경우 현재 입력 라인)입니다.
  2. = 공간. 공백 문자를 의미하는 경우 공백이나 탭 문자만 의미하는 경우 [[:space:]]또는 [[:blank:]]또는를 사용하세요.[ \t]
  3. .= 임의의 문자.

사용하는 명령은 grep다음과 같습니다.

grep -E '^ .*$*'

다음과 같은 문제가 있습니다.

  1. -Egrep기본 BRE 대신 ERE를 정규식으로 허용하지만 정규식에는 기본 정규식 구문이 아닌 항목이 없으므로 유용한 -E작업을 수행하지 않습니다.
  2. $버퍼의 끝(이 경우 입력 줄의 끝)을 나타내지 *만 메타 문자가 0개 이상 반복되므로 $*"버퍼 끝이 0개 이상 반복됨"을 의미합니다. 정의에 따라 끝은 1을 초과할 수 없습니다. 따라서 처리되는 버퍼는 의미가 없으며 사실상 POSIX에 따라 정의되지 않은 동작입니다.
  3. .*"문자가 0개 이상 반복됨"을 의미하지만 해당 위치에 문자가 1개 이상 있어야 한다는 요구 사항이 있으므로 이는 *잘못된 것입니다. .+ERE 또는 BRE에서 "하나 이상"을 의미하기 위해 사용할 수 있지만 요구 사항에 ..*단일 문자이면 충분하므로 "또는 그 이상"이 필요하지 않습니다. .즉, 1개 이상의 문자가 있으면 됩니다(1개이면 충분함).
  4. .*공백 뒤의 어떤 문자와도 일치하지 않지만 "모든 문자"는 최소한 1개의 문자를 의미한다고 가정합니다.

사용하는 명령은 sed다음과 같습니다.

sed 's/^ .*$//g'

다음과 같은 문제가 있습니다.

  1. grep과 sed는 모두 기본적으로 BRE에서 실행됩니다 -E. grep regexp가 필요하다고 생각되면 -E(필요하지 않음) -Esed를 사용하여 호출해야 합니다.
  2. grep 정규식 *끝에는 이 있습니다. 다시 말하지만, grep에 필요하다고 생각되면(그렇지 않음) sed regexp에도 있어야 합니다.
  3. grep 정규식과 마찬가지로 공백 뒤에 문자를 허용하지 않으려는 .*$경우가 아니면 작동 하지만 그것도 괜찮습니다...?.*
  4. grep정규식과 전역적으로 일치하고 결과를 인쇄하는 명령 g/re/p의 이름을 따서 명명되었습니다 . ed이를 고려하면 기본적으로 grep은 정규식과 일치하는 행만 인쇄한다는 것이 분명합니다. sed스트림 편집기이므로 사용자가 제공하는 모든 명령(현재 다른 명령)을 실행 ed하지만 다른 편집기와 마찬가지로 사용자가 지정하지 않으면 아무것도 삭제되지 않으므로 기본적으로 각 입력 줄이 인쇄됩니다. . sed그렇지 않은 경우에는 -n("기본적으로 인쇄하지 않음")을 사용하여 호출한 다음 p스크립트의 지침을 사용하여 특정 줄을 인쇄하도록 지시해야 합니다.
  5. sed 명령의 끝에서 gsed는 입력 줄에 나타날 때마다 정규식과 일치하도록 지시하지만 ^줄의 시작 부분에서는 한 번만 일치할 수 있고 $줄 끝에서는 한 번만 일치할 수 있습니다. 정규식은 한 줄에 한 번만 일치할 수 있으므로 gsed에게 정규식을 여러 번 일치시키도록 명령 끝에 a를 넣는 것은 좋지 않습니다.

기타 참고사항:

  1. sed의 GNU 및 BSD 변형만 -EERE를 지원하고 다른 모든 sed 변형은 BRE만 지원합니다.
  2. "I've try it"과 관련하여 - POSIX BRE 또는 ERE가 아닌 \s{1}PCRE의 POSIX 문자 클래스에 대한 약어입니다 . GNU sed 및 GNU grep은 BRE 또는 ERE, YMMV 및 비 GNU 변형 또는 PCRE 대신 BRE 및/또는 ERE와 함께 작동하는 기타 도구를 허용합니다 .\s[[:space:]]\s

관련 정보