Bash script para executar o comando em todos os arquivos em um diretório

Alguém poderia fornecer o código para fazer o seguinte: Suponha que haja um diretório de arquivos, todos os quais precisam ser executados através de um programa. O programa envia os resultados para o padrão. Eu preciso de um script que vá para um diretório, execute o comando em cada arquivo e concorde com a saída em um grande arquivo de saída.

Por exemplo, para executar o comando em um arquivo:

$ cmd [option] [filename] > results.out 

O seguinte código bash irá passar $ file para o comando onde $ file representará todos os arquivos em / dir

 for file in /dir/* do cmd [option] "$file" >> results.out done 

Exemplo

 el@defiant ~/foo $ touch foo.txt bar.txt baz.txt el@defiant ~/foo $ for i in *.txt; do echo "hello $i"; done hello bar.txt hello baz.txt hello foo.txt 

Que tal agora:

 find /some/directory -maxdepth 1 -type f -exec cmd option {} \; > results.out 
  • -maxdepth 1 argumento -maxdepth 1 impede que o find recursivamente -maxdepth 1 para quaisquer subdiretórios. (Se você quiser que esses diretórios nesteds sejam processados, você pode omitir isso.)
  • -type -f especifica que apenas arquivos simples serão processados.
  • -exec cmd option {} diz para executar cmd com a option especificada para cada arquivo encontrado, com o nome do arquivo substituído por {}
  • \; denota o fim do comando.
  • Finalmente, a saída de todas as execuções de cmd individuais é redirecionada para results.out

No entanto, se você se importa com a ordem em que os arquivos são processados, talvez seja melhor escrever um loop. Acho que os processos find os arquivos na ordem inode (embora eu possa estar errado sobre isso), o que pode não ser o que você quer.

Eu estou fazendo isso no meu pi framboesa a partir da linha de comando, executando:

 for i in *;do omxplayer "$i";done 

Baseado na abordagem de @Jim Lewis:

Aqui está uma solução rápida usando find e também classificar arquivos por sua data de modificação:

 $ find directory/ -maxdepth 1 -type f -print0 | \ xargs -r0 stat -c "%y %n" | \ sort | cut -d' ' -f4- | \ xargs -d "\n" -I{} cmd -op1 {} 

Para sorting, consulte:

http://www.commandlinefu.com/commands/view/5720/find-files-and-list-them-sorted-by-modification-time

Uma maneira rápida e suja que faz o trabalho às vezes é:

 find directory/ | xargs Command 

Por exemplo, para encontrar o número de linhas em todos os arquivos no diretório atual, você pode fazer:

 find . | xargs wc -l 

Eu precisava copiar todos os arquivos .md de um diretório para outro, então aqui está o que eu fiz.

for i in **/*.md;do mkdir -p ../docs/"$i" && rm -r ../docs/"$i" && cp "$i" "../docs/$i" && echo "$i -> ../docs/$i"; done

O que é muito difícil de ler, então vamos dividi-lo.

primeiro cd no diretório com seus arquivos,

for i in **/*.md; para cada arquivo no seu padrão

mkdir -p ../docs/"$i" esse diretório em uma pasta de documentos fora da pasta que contém seus arquivos. Que cria uma pasta extra com o mesmo nome daquele arquivo.

rm -r ../docs/"$i" remove a pasta extra que é criada como resultado de mkdir -p

cp "$i" "../docs/$i" Copie o arquivo real

echo "$i -> ../docs/$i" Echo o que você fez

; done ; done ao vivo feliz para sempre