Como usar o comando find no Linux – TopGadget
Home Dicas e Artigos Linux Como usar o comando find no Linux
Por Kayobrussy Guedes 7 de maio de 2022 Atualizado: 7 de maio de 2022 Nenhum comentário8 minutos de leitura
O comando find no Linux é ótimo para pesquisar arquivos e diretórios. Mas você também pode passar os resultados da pesquisa para outros programas para processamento posterior. Nós mostramos-lhe como.
O comando find do Linux
O comando Linux find é poderoso e flexível. Ele pode pesquisar arquivos e diretórios usando uma série de critérios diferentes, não apenas nomes de arquivos. Por exemplo, ele pode pesquisar arquivos vazios, arquivos executáveis ​​ou arquivos pertencentes a um usuário específico.
Ele pode encontrar e listar arquivos por seus horários acessados ​​ou modificados, você pode usar padrões regex, é recursivo por padrão e funciona com pseudo-arquivos como pipes nomeados (buffers FIFO).
Tudo isso é fantasticamente útil. O comando humilde find realmente tem algum poder. Mas há uma maneira de alavancar esse poder e levar as coisas para outro nível. Se pudermos pegar a saída do comando find e usá-la automaticamente como entrada de outros comandos, podemos fazer algo acontecer com os arquivos e diretórios que encontram descobertas para nós.
O princípio de canalizar a saída de um comando para outro comando é uma característica central dos sistemas operacionais derivados do Unix. O princípio de design de fazer um programa fazer uma coisa e fazê-lo bem, e esperar que sua saída possa ser a entrada de outro programa – mesmo um programa ainda não escrito – é frequentemente descrito como a "filosofia Unix". E, no entanto, alguns utilitários principais, como mkdir, não aceitam entrada canalizada.
Para resolver essa deficiência , o comando xargs pode ser usado para dividir a entrada canalizada e alimentá-la em outros comandos como se fossem parâmetros de linha de comando para esse comando. Isso alcança quase a mesma coisa que a tubulação simples. Isso é "quase a mesma coisa", e não "exatamente a mesma coisa", porque pode haver diferenças inesperadas com expansões de shell e globbing de nome de arquivo.
Usando find Com xargs
Podemos usar find com xargs alguma ação realizada nos arquivos que forem encontrados. Esta é uma maneira prolixa de fazer isso, mas poderíamos alimentar os arquivos encontrados por findinto xargs que então os canaliza tar para criar um arquivo desses arquivos. Executaremos este comando em um diretório que contém muitos arquivos PAGE do sistema de ajuda.
O comando é composto de diferentes elementos.
find ./ -name "*.page" -type f -print0: A ação find começará no diretório atual, procurando por nome por arquivos que correspondam à string de pesquisa "*.page". Os diretórios não serão listados porque estamos dizendo especificamente para procurar apenas arquivos, com -type f. O argumento print0 diz find para não tratar o espaço em branco como o final de um nome de arquivo. Isso significa que os nomes de arquivos com espaços neles serão processados ​​corretamente.
xargs -o : Os argumentos -0xargs para não tratar o espaço em branco como o final de um nome de arquivo.
tar -cvzf page_files.tar.gz : Este é o comando xargs que vai alimentar a lista de arquivos de find. O utilitário tar criará um arquivo chamado "page_files.tar.gz".
Podemos usar lspara ver o arquivo que é criado para nós.
O arquivo é criado para nós. Para que isso funcione, todos os nomes de arquivos precisam ser passados ​​para tar en masse , que foi o que aconteceu. Todos os nomes de arquivo foram marcados no final do tarcomando como uma linha de comando muito longa.
Você pode optar por executar o comando final em todos os nomes de arquivo de uma vez ou invocado uma vez por nome de arquivo. Podemos ver a diferença facilmente canalizando a saída xargs para o utilitário de contagem de linhas e caracteres wc.
Este comando canaliza todos os nomes de arquivos wc de uma vez. Efetivamente, xargs constrói uma longa linha de comando para wc cada um dos nomes de arquivo nela contidos.
As linhas, palavras e caracteres de cada arquivo são impressos, juntamente com o total de todos os arquivos.
Se usarmos a opção xarg's -I(replace string) e definirmos um token de string de substituição—neste caso " {}"—o token é substituído no comando final por cada nome de arquivo por vez. Isso significa que wcé chamado repetidamente, uma vez para cada arquivo.
A saída não está bem alinhada. Cada invocação de wcopera em um único arquivo, portanto wc, não tem nada para alinhar a saída. Cada linha de saída é uma linha de texto independente.
Como wcsó pode fornecer um total quando opera em vários arquivos ao mesmo tempo, não obtemos as estatísticas resumidas.
A opção find -exec
O comando find tem um método interno de chamar programas externos para realizar processamento adicional nos nomes de arquivo que ele retorna. A opção exec (executar) tem uma sintaxe semelhante, mas diferente do comando xargs.
find . -name "*.page" -type f -exec wc -c "{}" \;
Isso contará as palavras nos arquivos correspondentes. O comando é composto por esses elementos.
find . : inicia a pesquisa no diretório atual. O comando find é recursivo por padrão, portanto, os subdiretórios também serão pesquisados.
-name "*.page" : Estamos procurando arquivos com nomes que correspondam à string de pesquisa "*.page".
-type f : Estamos apenas procurando por arquivos, não por diretórios.
-exec wc : Vamos executar o comando wc nos nomes dos arquivos que correspondem à string de pesquisa.
-w : Quaisquer opções que você deseja passar para o comando devem ser colocadas imediatamente após o comando.
"{}" : o espaço reservado "{}" representa cada nome de arquivo e deve ser o último item na lista de parâmetros.
\;: Um ponto e vírgula ";" é usado para indicar o fim da lista de parâmetros. Ele deve ser escapado com uma barra invertida "\" para que o shell não o interprete.
Quando executamos esse comando, vemos a saída wc. A -c(contagem de bytes) limita sua saída ao número de bytes em cada arquivo.
Como você pode ver, não há total. O comando wc é executado uma vez por nome de arquivo. Ao substituir um sinal de mais " +" pelo ponto e vírgula final " ;" podemos mudar -exec comportamento do ' para operar em todos os arquivos de uma vez.
find . -name "*.page" -type f -exec wc -c "{}" \+
Obtemos o resumo total e os resultados tabulados ordenadamente que nos dizem que todos os arquivos foram passados ​​para wc uma longa linha de comando.
exec Realmente significa exec
A opção -exec (execute) não inicia o comando executando-o no shell atual. Ele usa o exec integrado do Linux para executar o comando, substituindo o processo atual – seu shell – pelo comando. Portanto, o comando que é iniciado não está sendo executado em um shell. Sem um shell, você não pode obter a expansão do shell de curingas e não tem acesso a aliases e funções do shell.
Este computador tem uma função shell definida chamada words-only. Isso conta apenas as palavras em um arquivo.
wc -w $ 1
Talvez uma função estranha, "somente palavras" seja muito mais longa para digitar do que "wc -w", mas pelo menos significa que você não precisa se lembrar das opções de linha de comando para wc. Podemos testar o que ele faz assim:
words-only user_commands.page
Isso funciona muito bem com uma invocação de linha de comando normal. Se tentarmos invocar essa função usando finda -exec opção , ela falhará.
find . -name "*.page" -type f -exec words-only "{}" \;
O findcomando não pode encontrar a função shell e a -execação falha.
Para superar isso, podemos com o find lançar um shell Bash e passar o restante da linha de comando para ele como argumentos para o shell. Precisamos colocar a linha de comando entre aspas duplas. Isso significa que precisamos escapar das aspas duplas que estão ao redor da string de substituição " {}".
Antes de podermos executar o comando find, precisamos exportar nossa função shell com a opção -f (como função):
find . -name "*.page" -type f -exec bash -c "words-only \"{}\"" \;
Isso é executado conforme o esperado.
Usando o nome do arquivo mais de uma vez
Se você quiser encadear vários comandos, você pode fazê-lo e pode usar a {}string de substituição " " em cada comando.
find . -name "*.page" -type f -exec bash -c "basename "{}" && words-only "{}"" \;
Se subirmos cd um nível do diretório "pages" e executarmos esse comando, find ainda descobriremos os arquivos PAGE porque ele pesquisa recursivamente. O nome do arquivo e o caminho são passados ​​para nossa função words-only como antes. Puramente por motivos de demonstração de uso -exec com dois comandos, também estamos chamando o comando basename para ver o nome do arquivo sem seu caminho.
Tanto o comando basename quanto a função shell words-only têm os nomes dos arquivos passados ​​a eles usando uma string de substituição " {} ".
Há uma carga de CPU e uma penalidade de tempo para chamar repetidamente um comando quando você pode chamá-lo uma vez e passar todos os nomes de arquivo para ele de uma só vez. E se você estiver invocando um novo shell toda vez para iniciar o comando, essa sobrecarga fica pior.
Mas às vezes – dependendo do que você está tentando alcançar – você pode não ter outra opção. Qualquer que seja o método que sua situação exija, ninguém deve se surpreender que o Linux forneça opções suficientes para que você possa encontrar aquele que atenda às suas necessidades específicas.