Ritorno ancora una volta sul problema della trasposizione di una colonna in riga applicato al caso di una query sql ma in questo caso voglio limitare il numero di parametri passati nella clausola where per controllare meglio il risultato della procedura e per limitare l’uso delle risorse di sistema. Quindi da un’unica colonna di valori ottengo diverse righe e non un’unica riga come nel precedente articolo. Ad esempio voglio selezionare (o cancellare) una serie di valori da una tabella in base a una lista di oggetti:

alex@vegeta:~$ cat lista_id.out | head -3
345B8F0740C03437DB55AFA27B1F9475
6180EE3E6DE5C24E09DCA8E40E2F669C
D9018BA57ECECDD83A322BD24EAAA8E1

Per semplicità mi limito a prendere una sequenza di 2 argomenti alla volta usando il parametro -n di xargs:

alex@vegeta:~$ cat lista_id.out | head -3 | xargs -n2
345B8F0740C03437DB55AFA27B1F9475 6180EE3E6DE5C24E09DCA8E40E2F669C
D9018BA57ECECDD83A322BD24EAAA8E1

Ora invece sostituisco, tramite il comando sed, lo spazio ” ” generato da xargs con la sequenza di caratteri “‘,'” (il comando tr permette di convertire un carattere in un altro mentre con il sed riesco a fare la conversione in un unico passaggio):

alex@vegeta:~$ cat lista_id.out | head -3 | xargs -n2 | sed 's/ /'\',\''/g'
345B8F0740C03437DB55AFA27B1F9475','6180EE3E6DE5C24E09DCA8E40E2F669C
D9018BA57ECECDD83A322BD24EAAA8E1

Infine posiziono un apice in testa:

alex@vegeta:~$ cat lista_id.out | head -3 | xargs -n2 | sed 's/ /'\',\''/g' | sed 's/^/'\''/'
'345B8F0740C03437DB55AFA27B1F9475','6180EE3E6DE5C24E09DCA8E40E2F669C
'D9018BA57ECECDD83A322BD24EAAA8E1

e un apice in fondo alla stringa:

alex@vegeta:~$ cat lista_id.out | head -3 | xargs -n2 | sed 's/ /'\',\''/g' | sed 's/^/'\''/' | sed 's/$/'\''/'
'345B8F0740C03437DB55AFA27B1F9475','6180EE3E6DE5C24E09DCA8E40E2F669C'
'D9018BA57ECECDD83A322BD24EAAA8E1'

Il tutto possiamo inserirlo all’interno di un ciclo while per generare il comando desiderato (in questo caso prendo 20 oggetti per ogni iterazione del ciclo):

TAB=table_a
SQL="select file from $TAB where file_id in"
while read LINE; do
	echo "$SQL $LINE"
done < <(cat lista_id.out | xargs -n20 | sed 's/ /'\',\''/g' | sed 's/^/'\''/' | sed 's/$/'\''/')

Posso miglioare l’output riportando il numero di righe elaborate e/o rimanenti:

NUM=$(wc -l lista_id.out | awk '{print $1}')
TAB=table_a
SQL="select file from $TAB where file_id in"
echo "Totale righe: $NUM"
while read LINE; do
	echo "$SQL $LINE" >> comando.sql
        NUM=$(($NUM - 20))
        if [ $NUM -ge 20 ]; then
                echo "Mancano ancora $NUM righe"
        fi
done < <(cat lista_id.out | xargs -n20 | sed 's/ /'\',\''/g' | sed 's/^/'\''/' | sed 's/$/'\''/')

[ad name=”HTML”]

Precedenti articoli: Prima parte e Seconda parte.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.