Ignora um trecho nawk se o arquivo de entrada estiver vazio

4

Eu tenho um script que gera vários arquivos de saída e usa esses arquivos de saída durante o tempo de execução. A seguir estão alguns dos arquivos gerados pelo script: apple.txt, section_fruit_out.csv, section_fruit_out_lookup.csv, food_lookup.csv, section_fruit_lookup.csv. Eu tenho uma frase de código como abaixo:

nawk 'FNR == NR && NF!=0 {x[$1] = $1; next;} {FS=OFS=","} FNR>1{if ($2 in x) {($6 = "apple")} } 1' apple.txt section_fruit_out.csv > section_fruit_out_lookup.csv 
nawk 'BEGIN { FS = OFS = ","; } FNR == NR { x[$1] = $2; next; } { if ($7 in x && $6 == "") { $6 = x[$7]; } else if ($6 == "" && $7 != "") { $6 = "TO_BE_DEFINED" } } 1' food_lookup.csv section_fruit_out_lookup.csv  > section_fruit_lookup.csv

Esta frase de código lida principalmente com o trabalho esperado. Mas o script não funciona como esperado se o arquivo apple.txt estiver vazio (esse arquivo é gerado por consultas de banco de dados). Se o arquivo apple.txt estiver vazio, o arquivo de saída (section_fruit_out_lookup.csv) da primeira seção nawk gerado também estará vazio. Como section_fruit_out_lookup.csv é gerado vazio e é usado pela segunda frase nawk, a segunda frase nawk também gera um arquivo de saída vazio (section_fruit_lookup.csv). Como posso ignorar a primeira frase nawk se o arquivo apple.txt estiver vazio e fazer a segunda frase nawk usar o arquivo section_fruit_out.csv em vez de usar o arquivo: section_fruit_out_lookup.csv?

    
por Murat 19.10.2015 / 10:43

2 respostas

7

há uma função test para o arquivo de tamanho zero.

if test -s apple.txt
then 
    ## apple.txt non empty
    code ...
else
    ## file empty
fi
    
por 19.10.2015 / 10:57
5

Em vez do teste NR == FNR para testar se você está processando o primeiro arquivo, é possível fazer isso:

awk 'FILENAME == ARGV[1] {...} ...' file1 file2

Mas esse é um teste mais caro, por isso, se file1 for um arquivo normal, você também deve usar a @ abordagem do Archemar e não executará awk se o primeiro arquivo estiver vazio.

Em casos (não seus) em que file1 e file2 precisam ser o mesmo arquivo, você pode fazer:

awk 'FILENAME == ARGV[1] {...} ...' file1 ./file1

Ou:

awk 'FILENAME == "-" {...} ...' - <file1 file1

Uma abordagem ainda melhor (portátil e eficiente):

awk '!file1_processed {...} ...' file1 file1_processed=1 file2

Se você precisar aplicar em ./*.txt , por exemplo, faça o seguinte:

set -- ./*.txt
first=$1; shift
awk '!first_processed {...} ...' "$first" first_processed=1 "$@"

Uma abordagem específica do GNU awk :

awk 'ARGIND == 1 {...} ...' file1 file2
    
por 19.10.2015 / 11:12

Tags