grep até 3 espaços com \ s

Oct 09 2020

De acordo com os seguintes tutoriais

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

\ s Corresponde a um espaço.

e

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

Algumas expressões regulares de intervalo são:

Descrição da Expressão

{n} Corresponde ao caractere anterior que aparece 'n' vezes exatamente

{n, m} Corresponde ao caractere anterior que aparece 'n' vezes, mas não mais do que m

{n,} Corresponde ao caractere anterior apenas quando aparece 'n' vezes ou mais

Arquivo de amostra

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

Eu só quero grep até 3 espaços apenas, mínimo 1 espaço, máximo 3 espaços Infelizmente, isso realmente não funciona como esperado.

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:~$ 

Resultado Desejado

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

Respostas

8 αғsнιη Oct 09 2020 at 12:25

você precisa:

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

\scorresponde a um caractere de espaço em branco, não apenas a um espaço.
\Scorresponde a um caractere não-espaço em branco

em sua tentativa, você não está limitando que antes e depois de suas partidas não deve ser um espaço em branco.


para filtrar apenas no espaço e evitar o uso de PCRE, você pode fazer:

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

ou para trabalhar em linhas com 1 a 3 espaços à esquerda / à direita:

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

dados de entrada ( cat -e infile):

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

resultado:

1 spaces$ 2 spaces$
3   spaces$ 3spaces$
3spaces   $
8 StéphaneChazelas Oct 09 2020 at 14:00

Se você deseja fazer a correspondência em uma sequência de 1 a 3 caracteres de espaço em branco não circundados por espaços em branco, é aí que você usaria os operadores look-around Perl:

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

Corresponde a:

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

Com o padrão grep, você pode obter o mesmo efeito com:

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

Desta vez, combinamos a sequência de 1 a 3 caracteres de espaço em branco e os espaços não em branco de cada lado (ou do início ( ^) ou do final ( $) do assunto).

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

(com -o(uma extensão GNU), você descobrirá que ele não relata a bcomo ajá foi correspondido anteriormente; ao pesquisar por mais correspondências, ele começa no próximo caractere após a última correspondência).

Sem -E, você obtém expressões regulares básicas que não têm operadores de alternância (embora algumas grepimplementações suportem \|isso como uma extensão), mas, normalmente, você ainda pode fazer:

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

Desta vez, o regexp corresponde a toda a linha incluindo os 1 a 3 espaços e uma parte inicial opcional ( \{0,1\}o equivalente a ERE ?) terminando em um espaço não em branco e uma parte opcional a seguir que começa com um espaço não em branco.

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

Em qualquer caso, eles ainda retornariam linhas que contêm uma sequência de 4 ou mais espaços em branco, desde que também contenham uma sequência de 1 a 3 espaços em branco não circundados por espaços em branco.

Se o objetivo fosse excluir linhas contendo sequências de 4 ou mais espaços em branco, seria apenas:

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

Ou se você ainda precisar de pelo menos um espaço em branco, ou em outras palavras, que a linha contenha uma ou mais sequências de caracteres de espaço em branco, todos com pelo menos um espaço em branco, mas não mais do que 3:

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

Isso retorna todas as linhas, exceto aquelas que contêm uma sequência de 4 espaços em branco e as que são feitas exclusivamente de não espaços em branco.

Ou novamente com o olhar ao redor dos operadores do Perl:

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

Isso corresponde ao início da linha, desde que seja seguido por qualquer quantidade de caracteres e um espaço em branco e que não seja seguido por qualquer quantidade de caracteres e uma sequência de 4 espaços em branco.

Embora fosse mais legível com sedou awkonde você pudesse fazer uma correspondência positiva e negativa na mesma invocação:

awk '/[[:space:]]/ && ! /[[:space:]]{4}/'
sed '/[[:space:]]/!d; /[[:space:]]\{4\}/d'
4 nezabudka Oct 09 2020 at 13:02

Você pode surgir do oposto. Exclua linhas com mais de 3 espaços na substring.

grep -Ev '\s{4,}'

-vInverta o sentido de correspondência, para selecionar linhas não correspondentes.
Você pode inserir âncoras como caracteres sem espaço em branco

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