Ciao a tutti,
Sto usando
Awk per processare 2 file di testo in modo da crearne un terzo opportunatamente formattato sulla base di stringhe in comune (poi vi spiego)
Vi spiego l' impasse in cui sono finito.
I 2 file di testo li chiamo g1.txt e g2.txt. Il primo,
g1, ha questo contenuto:
alfa beta;www.google.com
Light Dweller - CR, Technical Metal;http://alfa.org;http://beta.org;http://gamma.org;
il secondo,
g2, contiene, invece, questo testo
Jack to ride.zip;http://alfa.org;
JKr.rui.rar;http://gamma.org;
Nofj ogk.png;http://gamma.org;
Ora, io uso uno script per produrre il terzo file, g3.txt, formattato in questo modo
alfa beta;www.google.com
Light Dweller - CR, Technical Metal;http://alfa.org;http://beta.org;http://gamma.org;;Jack to ride.zip;JKr.rui.rar;Nofj ogk.png
Prima di mostrarvi il codice, vi spiego il perchè di questo output: sia nel file g1.txt e sia nel file g2.txt potete vedere delle stringhe in comune. Ad esempio, potete vedere che la stringa racchiusa dal separatore
; http://gamma.org
è presente in entrambi i file di testo. Nel caso di g1.txt questa stringa si trova alla seconda riga mentre in g2.txt la stessa stringa si trova sia sulla seconda nonchè sulla terza riga.
Il file g3.txt che cos'ha di particolare?
- le righe aventi le stringhe in comune sono raggruppate su un'unica riga e solo su una unica riga in tutto il file di testo. Quindi, la stringa
http://gamma.org
sarà presente una volta sola, non potrà trovarsi su una riga diversa.
- i doppioni vengono rimossi, ad esempio la stringa
http://gamma.org
viene visualizzata una volta sola sulla stessa riga, in altre parole non possiamo avere qualcosa di simile
http://gamma.org;JKr.rui.rar;http://gamma.org
perchè la stringa si ripete.
Allora, tutto questo lo faccio con questi 2 codici
unisci.awk
BEGIN {
OFS=FS=";"
}
ARGIND == 1 {
map[$2] = ($2 in map ? map[$2] OFS : "") $1
next
}
{
r = $0;
for (i=1; i<=NF; ++i)
if ($i in map)
r = r OFS map[$i]
$0 = r
}
1
e
unisci.sh
#! /usr/bin/awk -f
BEGIN {
OFS=FS=";"
C=0;
}
{
if (ARGIND == 1) {
X = $NF
T0[$NF] = C++
$NF = ""
if (T1[X]) {
T1[X] = T1[X] $0
} else {
T1[X] = $0
}
} else {
X = $NF
T0[$NF] = C++
$NF = ""
if (T2[X]) {
T2[X] = T2[X] $0
} else {
T2[X] = $0
}
}
}
END {
for (X in T0) {
# concatenate T1[X] and X, since T1[X] ends with ";"
print T1[X] X, T2[X]
}
}
Lo utilizzo in questo modo
awk -f unisci.awk g2.txt g1.txt
La ragione per cui ne ho 2 di codici (il primo si chiama unisci.awk e il secondo unisci.sh) è perchè altrimenti non mi verrebbe conservato l'ordine delle righe, cioè, eseguendo lo script mi viene fuori un output di questo genere
Light Dweller - CR, Technical Metal;http://alfa.org;http://beta.org;http://gamma.org;;Jack to ride.zip;JKr.rui.rar;Nofj ogk.png
alfa beta;www.google.com
Ma il file g1.txt ha prima la riga alfa beta.
Qual è il mio problema? Che lo script non mi funziona se ho questo testo nei 2 file di testo g1.txt e g2.txt
g1.txt
alfa beta;https://123.org/a/in.ph?shw=297585;
Light Dweller;https://123.org/a/in.ph?shw=3869;
Imp - Alp;https://123.org/a/in.ph?shw=340249;
g2.txt
Link;1996 7.zip;https://yd.k/d/BbNUb-2yhVmVnw;https://123.org/a/in.ph?shw=3869;https://123.org/a/in.ph?shw=3869&st=30;
Link;Moonblo (Tape)_123.zip;https://yd.k/d/57i;https://123.org/a/in.ph?shw=3869&st=30;
Link;Moonblo(Demo) [1996].rar;https://yd.k/d/A7U;https://123.org/a/in.ph?shw=3869;
L'output g3.txt che erroneamente mi produce è questo
alfa beta;https://123.org/a/in.ph?shw=297585;;;
Light Dweller;https://123.org/a/in.ph?shw=3869;;;
Imp - Alp;https://123.org/a/in.ph?shw=340249;;;
ma l'output che io mi aspetto che venga fuori dovrebbe essere invece
alfa beta;https://123.org/a/in.ph?shw=297585;
Light Dweller;https://123.org/a/in.ph?shw=3869;Link;1996 7.zip;https://yd.k/d/BbNUb-2yhVmVnw;https://123.org/a/in.ph?shw=3869&st=30;Link;Moonblo(Demo) [1996].rar;https://yd.k/d/A7U;
Imp - Alp;https://123.org/a/in.ph?shw=340249;