/ / Pesquise arquivos e execute um script em todos os resultados - unix, awk, find, xargs

Pesquise arquivos e execute um script em cada resultado - unix, awk, find, xargs

Gostaria de saber como pesquisar determinado padrão de arquivos em todos os subdiretórios (mês a mês / data - subdiretórios criados). E, em seguida, execute um script nos arquivos encontrados.

Etapa 1: Por exemplo: atualmente pesquisando arquivos neste padrão TT_DETAIL*.gz.

find /cygdrive/c/Test/  -name TT_DETAIL*.gz

saída # 1:

/cygdrive/c/Test/Feb2014/TT_DETAIL_20141115.csv.gz
/cygdrive/c/Test/Jan2014/TT_DETAIL_20141110.csv.gz
/cygdrive/c//Test/Mar2014/TT_DETAIL_20141120.csv.gz

Passo 2:

zcat TT_DETAIL*.gz | awk "BEGIN { FS=OFS=","} { if ($11=="10") print $2,$3,$6,$10,$11,$17}" >Op_TT_Detail.txt

cat Op_TT_Detail.txt

01-NOV-2014 00:30:53,AAA,ECH,1,10,XXX
01-NOV-2014 00:39:36,BBB,ECH,1,10,XXX
01-NOV-2014 00:39:44,CCC,ECH,1,10,XXX
01-NOV-2014 00:25:20,DDD,ECH,1,10,XXX

Tentei combinar os comandos abaixo como este, mas as etapas estão completas:

find /cygdrive/c/Test/  -name TT_DETAIL*.gz | xargs | zcat | awk "BEGIN { FS=OFS=","} { if ($11=="10") print $2,$3,$6,$10,$11,$17}" >>Op_TT_DETAIL.txt

find /cygdrive/c/Test/  -name TT_DETAIL*.gz -exec ./MonthwiseData.sh {} ;

Onde gato MonthwiseData.sh

zcat *.gz | awk "BEGIN { FS=OFS=","} { if ($11=="10") print $2,$3,$6,$10,$11,$17}" >>Op_TT_Detail.txt

Como posso fazer isso?

Respostas:

1 para resposta № 1

Acho que um while loop é a melhor maneira de lidar com estas situações:

while IFS= read -r file
do
awk "..." <(zcat "$file")
done < <(find . -type f -name "*gz")

Você tem um find comando enviado a um while ciclo. Dessa forma, você pode processar cada arquivo separadamente.

Então, é uma questão de executar uma awk "..." <(zcat "$file") ou zcat "$file" | awk "...".

No seu caso:

while IFS= read -r file
do
awk "BEGIN { FS=OFS=","} { if ($11=="10") print $2,$3,$6,$10,$11,$17}" <(zcat "$file") >>Op_TT_Detail.txt
done < <(find /cygdrive/c/Test/  -name TT_DETAIL*.gz)

Teste

Nós temos alguns gz arquivos no diretório atual:

$ for f in *gz; do echo "-- $f --"; zcat "$f"; done-- a.gz --
hello
bye
-- b.gz --
thisisB
bye

Vamos "s find imprima apenas o primeiro campo na primeira linha:

$ while IFS= read -r file; do awk "NR==1{print $1}" <(zcat "$file") >> output; done < <(find . -type f -name "*gz")

E a saída é:

$ cat output
thisisB
hello

Eu acho que você está procurando algo como isto:

find /cygdrive/c/Test/ -name "TT_DETAIL*.gz" -print0 | 
xargs -0 -I file zcat file | 
awk "BEGIN { FS=OFS=","} { if ($11=="10") print $2,$3,$6,$10,$11,$17}" >>Op_TT_Detail.txt
  • find localiza arquivos e -print0 imprime seu nome.
  • xargs -0 permite que você lide com o que vem do tubo anterior. Com -I file nós nomeamos file, para que possamos fazer zcat file | awk.

Leitura interessante: xargs: Como controlar e usar argumentos da linha de comando. </ s>


0 para resposta № 2

Você pode colocar o comando find em marcas de escala para criar uma lista de argumentos, como:

awk "{print $0}" `find . -type f -name "file*"` > concat_files.txt

Um exemplo simples fazendo o mesmo que concatenar todos os arquivos começando com "arquivo" realmente. São apenas as marcas que quero enfatizar aqui.