최대 3개의 공백을 입력하세요(\s 포함).

최대 3개의 공백을 입력하세요(\s 포함).

다음 튜토리얼에 따르면

  1. https://linuxize.com/post/regular-expressions-in-grep/

\s는 공백과 일치합니다.

그리고

  1. https://www.guru99.com/linux-regular-expressions.html

일부 간격 정규식은 다음과 같습니다.

표현 설명

{n}은 앞의 문자 "n"번과 정확히 일치합니다.

{n,m}은 앞의 문자 'n'번과 일치하지만 m 이하입니다.

{n, } 선행 문자가 "n"회 이상 나타나는 경우에만 해당 문자와 ​​일치합니다.

샘플 파일

wolf@linux:~$ cat space.txt
0space
1 spaces
2  spaces
3   spaces
4    spaces
wolf@linux:~$ 

최대 3개의 공간, 최소 1개의 공간, 최대 3개의 공간을 grep하고 싶습니다. 안타깝게도 예상대로 실제로 작동하지 않습니다.

wolf@linux:~$ cat space.txt | grep -P '\s{1,3}'
1 spaces
2  spaces
3   spaces
4    spaces
wolf@linux:~$ 

wolf@linux:~$ cat space.txt | grep -P '\s{3}'
3   spaces
4    spaces
wolf@linux:~$ 

wolf@linux:~$ cat space.txt | grep -P '\s{3,3}'
3   spaces
4    spaces
wolf@linux:~$ 

wolf@linux:~$ cat space.txt | grep -P '\s{0,3}'
0space
1 spaces
2  spaces
3   spaces
4    spaces
wolf@linux:~$ 

원하는 출력

wolf@linux:~$ cat space.txt | grep -P '\s{0,3}' <- need to fix it here
1 spaces
2  spaces
3   spaces
wolf@linux:~$ 

답변1

다음을 수행해야 합니다.

grep -P '\S\s{1,3}\S' infile

\s공백 문자와 일치합니다.뿐만 아니라공간.
\S공백이 아닌 문자와 일치

귀하의 시도에서는 경기 전후에 공백이 없어야 한다고 제한하지 않습니다.


공백만 필터링하고 PCRE를 방지하려면 다음을 수행할 수 있습니다.

grep '[^ ] \{1,3\}[^ ]' infile

또는 선행/후행 1~3개의 공백이 있는 줄에서 작업합니다.

grep '\([^ ]\|^\) \{1,3\}\([^ ]\|$\)' infile

https://regexper.com/에서 검색함

입력 데이터( cat -e infile):

0space$
1 spaces$
2  spaces$
3   spaces$
4    spaces$
   3spaces$
    4space$
3spaces   $
4spaces    $

산출:

1 spaces$
2  spaces$
3   spaces$
   3spaces$
3spaces   $

답변2

공백으로 둘러싸여 있지 않은 1~3개의 공백 문자 시퀀스를 일치시키려면 Perl 미리보기 연산자를 사용할 수 있습니다.

grep -P '(?<!\s)\s{1,3}(?!\s)'

다음과 일치합니다:

         1
1234567890123456789
    a b  c   d    e
     ^ ^^ ^^^ 

표준을 사용하면 grep다음과 같은 효과를 얻을 수 있습니다.

grep -E '(^|[^[:space:]])[[:space:]]{1,3}([^[:space:]]|$)'

이번에는 1~3개의 공백 문자와 그 뒤에 공백이 아닌 문자가 양쪽(또는 ^제목의 시작( ) 또는 끝( ))의 시퀀스와 일치합니다.$

         1
1234567890123456789
   a b  c   d    e
^^^^ ^^^^

((GNU 확장)을 사용하면 -o이전에 일치된 a b항목을 보고하지 않는다는 것을 알 수 있습니다 a. 더 많은 일치 항목을 검색할 때는 마지막 일치 항목 다음 문자에서 시작합니다.

그렇지 않은 경우 -E대체 연산자 없이 기본 정규식을 얻을 수 있지만(일부 grep구현에서는 \|이를 확장으로 지원하지만) 표준 사례에서는 여전히 다음과 같이 수행할 수 있습니다.

grep -x '\(.*[^[:space:]]\)\{0,1\}[[:space:]]\{1,3\}\([^[:space:]].*\)\{0,1\}'

이번에는 정규 표현식이 1~3개의 공백과 공백이 아닌 것으로 끝나는 선택적( \{0,1\}ERE 동등 ?) 선행 부분, 그 뒤에 공백이 아닌 것으로 시작하는 선택적 부분을 포함하여 전체 줄과 일치합니다.

         1
1234567890123456789
   a b  c   d    e
^^^^^^^^^^^^^^^^^^

그럼에도 불구하고, 공백으로 둘러싸여 있지 않은 1~3개의 공백 시퀀스도 포함하는 한, 이는 4개 이상의 공백 시퀀스가 ​​포함된 행을 반환합니다.

4개 이상의 공백이 포함된 행을 제외하려는 경우 다음과 같습니다.

grep -vE '[[:space:]]{4}'

또는 여전히 하나 이상의 공백이 필요한 경우, 즉 줄에 하나 이상의 공백 문자 시퀀스가 ​​포함되어 있으며 모두 공백이 하나 이상 있지만 3개를 넘을 수는 없습니다.

grep -vE -e '[[:space:]]{4}' -e '^[^[:space:]]*$'

즉, 공백이 4개 연속된 줄과 공백이 아닌 줄만 포함하는 줄을 제외한 모든 줄이 반환됩니다.

또는 Perl을 다시 사용하여 연산자를 확인하세요.

grep -P '^(?=.*\s)(?!.*\s{4})'

이는 뒤에 임의 개수의 문자와 공백이 오고 뒤에 임의 개수의 문자와 4개의 공백이 나오지 않는 경우 줄의 시작과 일치합니다.

sedor를 사용하면 awk동일한 호출에서 긍정적 일치와 부정적 일치를 모두 수행할 수 있지만 다음과 같이 하면 더 깔끔해집니다.

awk '/[[:space:]]/ && ! /[[:space:]]{4}/'
sed '/[[:space:]]/!d; /[[:space:]]\{4\}/d'

답변3

반대쪽에서 오시면 됩니다. 하위 문자열에서 공백이 3개 이상인 줄을 제외합니다.

grep -Ev '\s{4,}'

-v일치하지 않는 행을 선택하려면 일치의 의미를 반대로 합니다.
공백이 아닌 문자로 앵커를 삽입할 수 있습니다.

grep -E '\S\s{1,3}\S'

답변4

$ grep -E '[[:space:]]' < file |
  grep -vE '[[:space:]]{4}'
1 spaces
2  spaces
3   spaces
  • 먼저 공백 문자가 1개 이상 포함된 모든 줄을 필터링합니다.
  • 여기에서 4개 이상의 공백 문자가 포함된 모든 줄을 필터링합니다.
  • 남은 것은 1~3개의 공백 문자로 구성된 줄입니다.

관련 정보