Aplique um comando a todos os subdiretórios / arquivos

1

Em um diretório pai, eu tenho vários subdiretórios, cada um deles contém um ou mais arquivos de texto delimitados por espaço.

Eu tenho o seguinte comando que gera o que eu quero, mas apenas para um arquivo individual INPUTFILE.txt

awk '{if (NF>4){print $1, $2, $3 , "0" } else {print $0}}' INPUTFILE.txt

Considerando o fato de que eu tenho milhares de subdiretórios, e os nomes dos arquivos variam, como posso aplicar este comando a todos os subdiretórios; do diretório pai?

    
por steve 17.11.2015 / 20:22

3 respostas

3

Primeiro, cd para o diretório pai desejado.

Em seguida, use o comando find para executar o comando awk :

find -type f -exec awk '{if (NF>4){print $1, $2, $3 , "0" } else {print $0}}' {} +

Explicação

  • já é recursivo por padrão, portanto, isso será executado para todos os subdiretórios
  • -type f limitará a localização de f iles, em vez de arquivos e diretórios
  • a sintaxe -exec somecommand {} + executa um comando e coloca os caminhos de arquivo encontrados onde você escreve {}
  • a opção + foi considerada mais eficiente porque só executa uma instância de awk enquanto coloca os resultados da pesquisa como argumentos em {} , enquanto a outra forma de executá-la (não mostrada aqui) seria executada awk uma vez por cada nome de arquivo e é considerado menos eficiente
por 17.11.2015 / 20:47
1

Ok A maneira rápida e suja de fazer isso é com um loop, mas precisamos definir algumas coisas primeiro. O seguinte lhe dará um arquivo de texto com nomes e caminhos dos arquivos nos quais você deseja executar o comando awk. Você precisará executá-lo a partir do diretório pai.

find . -type f -print >> source.txt

Então você executa o loop

for i in $(cat source.txt); do 
  awk '{if (NF>4){print $1, $2, $3 , "0" } else {print $0}}' $i >> OUTPUTFILE.txt
done

Não ficou claro se você queria um único arquivo de saída se quisesse vários arquivos de saída.

Se você quiser vários arquivos de saída, você pode fazer isso:

for i in $(cat source.txt); do 
  awk '{if (NF>4){print $1, $2, $3 , "0" } else {print $0}}' $i >> $i.processed.txt
done
    
por 17.11.2015 / 20:39
1

UPDATE : A questão mudou depois que a resposta foi escrita ...

for a in */INPUTFILE.txt
do 
   cp "$a" "$a.bak" 
   YOUR-AWK "$a.bak" > "$a" 
done

A nova pergunta parece estranha !! Se eu entendi corretamente

YOUR-AWK */*.txt > output.txt
    
por 17.11.2015 / 20:44