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.
filenos 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 findcomando 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 filecomando 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 findcomando, 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 finde é a marca de pontuação no final do nosso -execcomando. 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 findcomando (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 grepcomando retornar verdadeiro. Voila.
find . -type f -exec grep -Il "" {} \;.