Ajuda com expressão regular no grep

1

alguém pode me explicar por que esse regexp não funciona no grep?

ls -la ./ | grep -E '^d.*\<\..*\>$'

Na minha opinião (errada), isso tem que me mostrar a linha do diretório com um nome que comece com ".", porque:

  • ^ d - > manter linhas que começam com o caractere "d"
  • . * - > nenhuma ou qualquer combinação de caracteres
  • $ - > fim da linha

O problema é que eu não entendo isso:

  • \ < - > início da palavra
  • - > escapar do ponto
  • . * - > nenhuma ou qualquer combinação de caracteres
  • > - > fim da palavra

Então, pensei que essa parte do regexp mantém as linhas que contêm palavras que começam com ponto e terminam com uma combinação de caracteres.

Com este "ls -la" esse regexp com grep não mostra nenhum resultado:

[arch dirtest]$ ls -la
total 52
drwxr-xr-x  6 siv users 4096 10 nov 00.41 .
drwx------ 59 siv users 4096  9 nov 23.15 ..
drwxr-xr-x  2 siv users 4096 10 nov 00.41 .test
drwxr-xr-x  2 siv users 4096 10 nov 00.41 test1
drwxr-xr-x  2 siv users 4096 10 nov 00.41 test2
    
por siv-lab 10.11.2015 / 00:43

2 respostas

4

Sua expressão regular não funciona porque . não é um caractere de palavra. O grep considera apenas a-z , A-Z , 0-9 e _ como caracteres de palavras.

De qualquer forma, essa não é a maneira correta de fazer isso. Primeiro de tudo, analisar ls é muito frágil e quase nunca é uma boa ideia. Aqui estão algumas outras maneiras de listar diretórios cujo nome começa com . :

find . -type d -name '.*'

Ou, se você não quiser que ele desça em subdiretórios (e se você tiver o GNU find , o padrão no Linux):

find . -maxdepth 1 -type d   -name '.*' 

Como alternativa, você pode usar apenas echo e um shell glob:

echo .*

Isso também mostrará arquivos. Para evitar isso, use um loop como:

for i in .*; do [ -d "$i" ] && printf '%s\n' "$i"; done
    
por 10.11.2015 / 01:00
1

Você parece ter omitido um método de dispositivo depois de -D ?

ls -la ./ | grep -D skip '^d.*\<\..*\>$'

De qualquer forma ... o problema é que você está procurando por um começo de palavra limite, \< , seguido por um ponto literal, \. . Isso sempre falhará porque um ponto não é considerado um caractere de palavra. Citação de info grep para o GNU grep:

'-w'
'--word-regexp'
     ... Word-constituent characters are letters, digits, and the underscore.

Substituir \< por um espaço parece funcionar de forma confiável. No entanto, eu concordo com user: terdon que a análise da saída de ls -la é frágil e existem maneiras melhores de conseguir o que você quer.

    
por 10.11.2015 / 01:16