Sim, existem várias maneiras de fazer isso com o comando find . Vou listar alguns na ordem que acho importante para entender sua situação.
-
Seu script parece aceitar vários argumentos de nome de arquivo, portanto, a maneira mais eficiente e quase universal de realizar isso usando o comando
findé:find ~/foo -type f -name \*.txt -exec perl ~/script.pl {} +Isso executa o seu script com tantos argumentos de nome de arquivo encontrados quanto possível. Seu script será chamado várias vezes, se necessário, para processar todos os nomes de arquivos. Observe o
+no final da linha. -
Este é o método original e mais universal. Isso é menos eficiente para sua situação porque invoca
perluma vez para cada arquivo encontrado. Esse uso está disponível desde os primeiros dias do Unix . Observe o ponto e vírgula escapado (\;) no final da linha (em oposição ao+acima).find ~/foo -type f -name \*.txt -exec perl ~/script.pl {} \; -
Antes de a sintaxe
-exec ... +ser adicionada afind, o comandoxargsfoi inventado para ajudar a aumentar a eficiência ao processar listas de nomes de arquivos ou outros argumentos. Isso funciona quase de forma idêntica ao exemplo-exec ... +acima:find ~/foo -type f -name \*.txt -print | xargs perl ~/script.plSe sua implementação for compatível, você deve usar a opção
-print0defind, junto com o argumento-0paraxargs. Isso faz com quefindimprima caracteres nulos entre as sequências de argumentos e impede quexargsdivida os argumentos em nada, exceto no caractere nulo. Isso ajuda a impedir quexargsdivida os argumentos incorretamente, caso seus nomes de arquivos contenham espaços em branco ou outros caracteres especiais.Usar a sintaxe
-exec ... +geralmente é uma ideia melhor porquefindcoloca os nomes de arquivos diretamente na lista de argumentos do seu script, eliminando um processo e evitando qualquer interpretação que possa ocorrer ao canalizar paraxargs. No entanto,xargspode ter vantagens se você precisar de mais controle sobre o processo. Veja a páginaxargsman. -
Você também pode verificar o comando
find2perl, que recebe os mesmos argumentos definde imprime um programaperlpara fazer a mesma coisa. Você poderia então incorporar o códigoperlgerado em seu script. No script gerado abaixo, você modificaria o próximo da última linha para chamar sua função em vez deprint.$ find2perl foo -type f -name \*.txt # /* #[some preamble code removed for brevity] # Traverse desired filesystems File::Find::find({wanted => \&wanted}, 'foo'); exit; sub wanted { my ($dev,$ino,$mode,$nlink,$uid,$gid); (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _ && /^.*\.txt\z/s && print("$name\n"); }