Por que o comando pipe "l | grep ”1“ ”obteve o resultado errado?

13

Como a figura ilustra, eu uso lo arquivo na pasta atual. E então eu quero obter o arquivo com número 1, então eu uso pipeoe o grep.

Mas por que o arquivo 2e 22é exibido? E qual é o 1;34m?

$ l
./ ../ 1 11 2 22
$ l | grep "1"
1;34m./ 1;32m../ 1 11 2 22

Atualizar

Eu já tenho o apelido no comando lno meu zshrcarquivo.

 alias lsp="ls"
 alias ll='ls -alF'
 alias la='ls -A'
 alias l='ls -CF'
 alias ls="ls -alh --color"

E aqui está o resultado do typecomando:

>$ type ls
ls is an alias for ls -alh --color

> $ type l
l is an alias for ls -CF
Lee
fonte
4
Por favor, não poste capturas de tela de texto. Copie o texto aqui e aplique a formatação do código.
Muru
@uru Eu acho que você queria pedir a saída de post type -a l?
WinEunuuchs2Unix
@ WinEunuuchs2Unix ah, sim.
Muru
@ Lee posso pedir que você publique a saída do type lscomando, por favor? você modificou o lsalias de alguma forma?
Sergiy Kolodyazhnyy
@Serg já atualizado.
Lee

Respostas:

27

Primeiro de tudo, o que você está tentando fazer l| grep <filename>é ruim. Não faça isso. Aqui está o porquê.

l comando é realmente um alias para ls -CF

$ type -a l
l is aliased to `ls -CF'

Por padrão no Ubuntu bash, lsé um apelido para ls --color=auto. Como a chave de aço apontada nos comentários --color=autodeve desativar a colorização. No seu caso específico, você tem alias ls="ls -alh --color"e alias l="ls -CF", que basicamente acaba sendo ls -alh --color -CF. Essa combinação específica de switches ainda envia saída colorida sobre um tubo. Por exemplo:

$ ls -alh --color -CF ~/TESTDIR | cat -A                                                                                 
^[[0m^[[01;34m.^[[0m/  ^[[01;34m..^[[0m/  1.txt  2.txt  3.txt  out.txt$

Observe como os diretórios .e ..têm as mesmas seqüências de escape.

O que tudo isso significa

Isso significa que lproduzirá uma lista colorida de arquivos de acordo com o tipo de arquivo. O problema é que a colorização acontece com o uso de seqüências de escape . Isso é o que as 1:34mcoisas são - elas são uma sequência de escape para cores específicas.

O principal problema é que a análise lsgeralmente leva a resultados e desastres errados nos scripts, simplesmente porque lspermite seqüências de escape como explicadas anteriormente e outros caracteres especiais. Consulte este artigo para obter mais informações: http://mywiki.wooledge.org/ParsingLs

O que você deve fazer:

Use o findcomando:

bash-4.3$ ls
1.txt  2.txt  3.txt  out.txt
bash-4.3$ find . -maxdepth 1 -iname "*1*"
./1.txt

Você poderia fazer algo assim com o shell glob e o [[comando de teste moderno :

bash-4.3$ for file in * ;do if [[ "$file" =~ "1"  ]] ;then echo "$file" ;fi ; done
1.txt

Ou talvez use python, que possui recursos de manipulação de nome de arquivo muito melhores do que bashsozinho

bash-4.3$ python -c 'import os;print [f for f in os.listdir(".") if "1" in f ]'
['1.txt']

Se não houver necessidade de processar a saída ls, o simples globbing também lspode fazer o trabalho. (Lembre-se, isso é apenas para visualizar a lista de arquivos, não para transmiti-la para outro programa para lidar com o texto de saída)

bash-4.3$ ls *1*
1.txt
Sergiy Kolodyazhnyy
fonte
2
Eu acho que a saída só será colorida em um pipe se --color=alwaystambém for especificado - como parte do alias para lou em um alias anterior para lssi (substituindo o padrão alias ls='ls --color=auto').
steeldriver
@steeldriver Bom ponto, mas não é isso que acontece lsno bash por padrão? type lsdá-me que é um apelido para #ls --color=auto
Sergiy Kolodyazhnyy
1
Sim, esse é o padrão - mas autodesativa a cor em um tubo AFAIK. Para ver sequências de cores ANSI, ele deve ter sido alterado para --color=always, no lsalias ou no lalias
steeldriver
Oh, entendo o que você quer dizer. Isso é muito estranho.
Sergiy Kolodyazhnyy
@steeldriver Então solicitei ao OP que publicasse seus pseudônimos, e aparentemente o que eles têm, ou seja ls --color, não impede a colorização (testei isso também).
Atualizei
6

Seus comandos le lssão configurados como aliases.

Quando você os executa, canaliza a saída através de grep "1"(usando |) cada linha da tela em que 1aparece é exibida, com a 1cor vermelha.

Como os nomes de arquivo ., .., 2e 22aparecem na mesma linha de tela, eles são emitidos por grepbem, mas não aparecem em vermelho que mostra greppartidas.

A :34mé uma sequência de escape para uma cor que não pintar corretamente. Com base na sua pergunta revisada, com a saída de type -a le type -aela pode ser reproduzida no meu sistema. Observe que você deve alterar seu alias de --colorpara --color=auto:

Saída colorida

cor ls

WinEunuuchs2Unix
fonte
As 1:34mcoisas não são corrupção, são seqüências de escape usadas para colorir o texto. Veja minha resposta nessa parte;)
Sergiy Kolodyazhnyy
@Serg Obrigado. Revisei com base na pergunta revisada do OP com aliases.
WinEunuuchs2Unix
1

No seu julgamento, você estava chamando seu lsapelido, portanto, o1;34m ruído semelhante que vem da coloração e, como o tubo |recebe tudo isso na mesma linha, ele grepcorresponde ao arquivo 1dessa linha e, consequentemente, imprime essa linha. Isto é o que você vê na tela.

Quando você está fazendo coisas assim, é sempre bom voltar ao comando do sistema com 1 resultado por linha.

Para se livrar dos aliases, basta digitar \lse usar a opção -1para imprimir resultados separados por feeds de linha.

$ \ls -1 | grep "1"
1
11

Nota: o método de barra invertida funciona com todos os comandos, \commandapenas chama o comando do sistema sem serrilhado.

pilko
fonte