ls | grep funciona não funciona com ls --color

2

Estou tentando listar todos os diretórios ocultos com o seguinte comando

ls -lhAF1 | grep -E '^d.*[0-9]{2}:[0-9]{2} \.'

que funciona perfeitamente bem

Explanation for Regex: I'm trying to get all rows that have the following Format: d, then some text, then the timestamp, then a space, then the dot and then more text

No entanto, quando tento colorir a saída ls com este comando:

ls --color -lhAF1 | grep -E '^d.*[0-9]{2}:[0-9]{2} \.'

Não dá resultados, a saída sem --color é:

drwxr-xr-x 1 User Group 4096 Feb 1 08:48 .invisible

Por que o ls / grep se comporta dessa maneira?

    
por danielr1996 02.02.2016 / 09:35

5 respostas

6

--color adiciona sequências de escape para a cor. Você pode ver isso se você redirecionar a saída (de ls --color ) para um arquivo.

Isto é o que parece:

 drwxr-xr-x  6 root root 4.0K Jan  9 08:23 ^[[01;34m.cabal^[[0m/

Para dar conta disso, tente isso:

 ls -lhAF1 --color | grep -E '^d.*[0-9]{2}:[0-9]{2} .*\.'
    
por 02.02.2016 / 09:53
6

Analisar ls é geralmente uma má ideia . Muitas vezes, mas nem sempre . Aqui está outra sugestão para você, que coleta os diretórios necessários juntos antes de passar o conjunto para ls .

find .* -maxdepth 0 -type d \( -name '.[^.]' -o -name '.??*' \) -exec ls -ld --color=always {} +

Tem sido apontado que o código original realmente limita a lista de diretórios àqueles modificados nos últimos seis meses. Isso pode ser tratado com a seguinte solução alternativa.

find .* -maxdepth 0 -type d -mtime -180 -mtime +0 \( -name '.[^.]' -o -name '.??*' \) -exec ls -ld --color=always {} +

Como sempre, se o seu find não entender o + à direita, substitua-o por \; ao custo de eficiência.

    
por 02.02.2016 / 12:39
2

O motivo é que ls sempre coloriza sua saída mesmo se estiver conectado a um terminal. De man ls :

   --color[=WHEN]
          colorize the output.   WHEN  defaults  to  'always'  or  can  be
          'never' or 'auto'.  More info below

Muitas outras ferramentas, como grep , não retêm cores quando a saída padrão é terminal, mas por alguns motivos ls foi projetado para agir de maneira diferente. A saída de colorização é obtida usando códigos de escape ANSI que são interpretados pelo seu terminal. Redirecione ls output para um arquivo e abra-o no editor:

$ ls --color  -lhaF1  > /tmp/RESULT
$ less /tmp/RESULT
total 12K
drwxr-xr-x  3 ja   users 4.0K Feb  2 09:47 ESC[0mESC[01;34m.ESC[0m/
drwxrwxrwt 12 root root  4.0K Feb  2 09:51 ESC[30;42m..ESC[0m/
drwxr-xr-x  2 ja   users 4.0K Feb  2 09:47 ESC[01;34m.invisibleESC[0m/
-rw-r--r--  1 ja   users    0 Feb  2 08:35 a|a

Se você tiver o valor da variável $LESS , provavelmente precisará desativá-lo antes de executar less para ver os códigos de escape brutos em vez da cor. Então, para resumir, quando usar --color o que grep obtém não é o que você vê, mas um monte de códigos de escape junto com ele. Para corrigir isso, não use --colors ou configure-o como --auto :

$ ls --color=auto -lhaF1 | grep  -E '^d.*[0-9]{2}:[0-9]{2} \.'
    
por 02.02.2016 / 10:00
0

Ok, finalmente descobri como listar todos os diretórios ocultos, preservando as cores e não incluindo diretivas como "hello.world":

 ls -lhAF1 --color | grep -E "^d[rwx-]{9}.*[0-9]{2}:[0-9]{2} "$'\x1b'"\[([0-9]{1,2}m?)(;[0-9]{1,2}m?)?\."
    
por 02.02.2016 / 11:08
0

Em vez de aplicar grep à saída de ls , que não é processável de maneira confiável, prefiro filtrar a lista de arquivos que passam para ls , como:

ls -lFhd --color -- .*(/)

Em zsh . Ou, como sua própria abordagem sugere, você deseja apenas que os diretórios tenham sido modificados pela última vez há 6 meses e agora e não aqueles com permissões especiais:

ls -lFhd --color -- .*(/mM-6mM+0f-7000)
    
por 02.02.2016 / 13:05