Usando entrada de dois arquivos diferentes em um loop for

1

Eu tenho uma lista de arquivos que eu quero pesquisar em uma lista de tabelas de banco de dados:

[root@host hs]# head -n 3 tables
rec_playinth120116
rec_playinth120216
rec_playinth120316
[root@host hs]# head -n 3 files
0128184628OV30.wav
0128780332OV30.wav
0128439969OV30.wav

Estou tentando simplificar o processo criando um script de shell simples que apenas analisa os arquivos de entrada e envia os resultados para um terceiro arquivo contendo o caminho completo de cada arquivo. Essencialmente isso (o sed limpa a saída em um caminho de arquivo normal que pode ser usado como entrada em outro processo):

psql -d task_hst -A -P tuples_only=on -c "select f_path, file_name from $TABLES where file_name = ''$FILES''"|sed 's/|/\//g' >> $OUT

Quando isso é executado em um loop for que obviamente não compara cada arquivo em cada tabela. A única maneira de obter a saída desejada é codificar cada tabela e executá-las como comandos individuais, por exemplo:

for x in $FILE
do

psql -d task_hst -A -P tuples_only=on -c "select f_path, file_name from rec_playinth120116 where file_name = '$x'"|sed 's/|/\//g' >> $OUT
psql -d task_hst -A -P tuples_only=on -c "select f_path, file_name from rec_playinth120216 where file_name = '$x'"|sed 's/|/\//g' >> $OUT
psql -d task_hst -A -P tuples_only=on -c "select f_path, file_name from rec_playinth120316 where file_name = '$x'"|sed 's/|/\//g' >> $OUT

Esta não é a maneira mais elegante ou amigável de fazer as coisas.

Idealmente, os nomes dos arquivos seriam entradas passadas ao executar o script, algo assim:

while true
do
        read -r f1 <&3 || break
        read -r f2 <&4 || break
        psql -d task_hst -A -P tuples_only=on -c "select f_path, file_name from $f1 where file_name = '$f2'"|sed 's/|/\//g' >> $OUT
done 3<$1 4<$2

No entanto, isso será interrompido depois que o primeiro resultado for encontrado, quando eu precisar continuar pesquisando em todas as tabelas especificadas.

Eu sei que há uma maneira de fazer isso com while ou paste ou algo assim, mas está fora do meu conjunto de habilidades. Existe uma maneira simples de conseguir isso?

    
por has 27.12.2016 / 15:56

1 resposta

0

@barun Sim, é exatamente isso, embora eu não soubesse que "produto cartesiano" era o termo para descrevê-lo. Eu fiz algumas pesquisas com essa informação e descobri isso:

while read line1
do
    while read line2
    do psql -d task_hst -A -P tuples_only=on -c "select f_path, file_name from $line1 where file_name = '$line2'"|sed 's/|/\//g' >> $OUT
    done < $2
done < $1

Isso parece fazer o trabalho. Obrigado pela sua resposta! Existe uma maneira melhor de fazer isso?

    
por 27.12.2016 / 17:00