Esta é uma versão simplificada com explicação estendida para iniciantes como eu que estão tentando aprender como colocar mais de um comando em uma linha.
Se você escrevesse o problema em etapas, seria assim:
// For every file in this directory
// Check the filetype
// If it's an ASCII file, then print out the filename
Para isso, podemos usar três comandos UNIX: find
, file
, e grep
.
find
irá verificar todos os arquivos no diretório.
file
nos dará o tipo de arquivo. Em nosso caso, estamos procurando um retorno de 'texto ASCII'
grep
irá procurar a palavra-chave 'ASCII' na saída de file
Então, como podemos amarrá-los em uma única linha? Existem várias maneiras de fazer isso, mas acho que fazê-lo na ordem de nosso pseudocódigo faz mais sentido (especialmente para um iniciante como eu).
find ./ -exec file {} ";" | grep 'ASCII'
Parece complicado, mas não é ruim quando o dividimos:
find ./
= examine cada arquivo neste diretório. O find
comando imprime o nome do arquivo de qualquer arquivo que corresponda à 'expressão', ou o que vier depois do caminho, que no nosso caso é o diretório atual ou./
A coisa mais importante a entender é que tudo após o primeiro bit será avaliado como verdadeiro ou falso. Se for True, o nome do arquivo será impresso. Se não, o comando segue em frente.
-exec
= este sinalizador é uma opção dentro do comando find que nos permite usar o resultado de algum outro comando como a expressão de pesquisa. É como chamar uma função dentro de uma função.
file {}
= o comando sendo chamado dentro de find
. O file
comando retorna uma string que informa o tipo de arquivo de um arquivo. Regularmente, ele ficaria assim: file mytextfile.txt
. Em nosso caso, queremos que ele use qualquer arquivo que esteja sendo examinado pelo find
comando, então colocamos as chaves {}
para atuar como uma variável vazia ou parâmetro. Em outras palavras, estamos apenas pedindo que o sistema produza uma string para cada arquivo no diretório.
";"
= isso é exigido por find
e é a marca de pontuação no final do nosso -exec
comando. Consulte o manual para 'encontrar' para obter mais explicações se precisar executando man find
.
| grep 'ASCII'
= |
é um tubo. Pipe pega a saída de tudo o que está à esquerda e a usa como entrada para o que está à direita. Ele pega a saída do find
comando (uma string que é o tipo de arquivo de um único arquivo) e a testa para ver se contém a string 'ASCII'
. Em caso afirmativo, ele retorna verdadeiro.
AGORA, a expressão à direita de find ./
retornará verdadeiro quando o grep
comando retornar verdadeiro. Voila.
find . -type f -exec grep -Il "" {} \;
.