View Full Version : Piccolo aiuto con uno script
DigitalKiller
21-06-2007, 17:25
Devo scrivere un piccolo script di shell, che partendo da un file in questo formato:
V000001......................................
V000001......................................
V000001......................................
B000001......................................
B000001......................................
v000002......................................
B000002......................................
B000002......................................
v000002......................................
B000003......................................
B000003......................................
v000003......................................
B000003......................................
B000004......................................
v000004......................................
B000005......................................
B000005......................................
v00000n......................................
mi generi n file in quest'altro formato:
file000001:
V000001......................................
V000001......................................
V000001......................................
B000001......................................
B000001......................................
file000002:
v000002......................................
B000002......................................
B000002......................................
v000002......................................
file00000n:
v00000n......................................
In pratica, nello script devo indicare quali codici andare a cercare (000001, 000002, ecc), scorrere il file di partenza n volte e generare i file di destinazione.
Mi potreste dire come fare a ricercare la stringa nel file ed a copiare l'intera riga in un altro file? Il resto dello script vorrei provare a scriverlo da solo...
Grazie:D
In pratica, nello script devo indicare quali codici andare a cercare (000001, 000002, ecc), scorrere il file di partenza n volte e generare i file di destinazione.
Non credo che serva scorrere il file n volte. Penso che basti usare sed e si risolve il problema. Ora provo a farlo:
Metto il tag spoiler se non vuoi vedere lo script completo.
#!/bin/bash
FILE_DI_PARTENZA=$1
for a in $(cat $FILE_DI_PARTENZA)
do
echo $a >> file$(echo $a | sed 's/.\([^.]*\).*/\1/g')
done
Vedi un po' se funge... non l'ho testato.
DigitalKiller
21-06-2007, 18:25
Grazie per la risposta!:)
Ho provato il tuo script, ma non ottengo ciò che vorrei. Così com'è, lo script mi genera tanti file quante sono le righe e, mi sembra, anche per le colonne.:(
Forse mi sbaglio, ma credo che ti abbiano confuso quei puntini che ho inserito descrivendo il file.
Il file in questione è a formato fisso a 185 colonne e comprenden vari caratteri e spazi.
Ecco un esempio reale
V0000013605015SUCCO F.JOLLY PESCAX3 BRML0200 003158158005JOLLY X 3 8 53 8520MLLT 0,600 12 11 8002700219203 0 01 0 0 0 0 0
Grazie:)
Forse ho capito. Riprova così:
#!/bin/bash
FILE_DI_PARTENZA=$1
for a in $(cat $FILE_DI_PARTENZA)
do
echo $a >> file$(echo $a | cut -c 2-7)
done
DigitalKiller
21-06-2007, 19:05
Forse ho capito. Riprova così:
#!/bin/bash
FILE_DI_PARTENZA=$1
for a in $(cat $FILE_DI_PARTENZA)
do
echo $a >> file$(echo $a | cut -c 2-7)
done
No, purtroppo lo script continua a generare 1 file per ogni riga ed ogni colonna. A me, invece, servirebbe un unico file in cui sono compiate tutte le righe con lo stesso codice (il codice sono i 6 caratteri dopo la V o la B)
No, purtroppo lo script continua a generare 1 file per ogni riga ed ogni colonna.
AAAAh! Certo! Ci sono gli spazi che fanno danno! Prova così:
#!/bin/bash
IFS_BAK=$IFS
IFS=$'\n'
FILE_DI_PARTENZA=$1
for a in $(cat $FILE_DI_PARTENZA)
do
echo $a >> file$(echo $a | cut -c 2-7)
done
IFS=$IFS_BAK
gurutech
22-06-2007, 10:27
AAAAh! Certo! Ci sono gli spazi che fanno danno! Prova così:
#!/bin/bash
IFS_BAK=$IFS
IFS=$'\n'
FILE_DI_PARTENZA=$1
for a in $(cat $FILE_DI_PARTENZA)
do
echo $a >> file$(echo $a | cut -c 2-7)
done
IFS=$IFS_BAK
non credo che funzioni ... in questo modo non dividi i codici uno dall'altro.
innanzitutto non sappiamo a priori quanti sono i codici.
sappiamo solo che ogni codice e' formato da una lettera (che ci e' indifferente se ho capito bene) e 6 cifre. per cui dobbiamo selezionare tutti i codici numerici in un file e poi splittare in tanti file con ogni codice
con questo file di test:
gianluca@gurutech:~$ cat test
V000001ASDJHWIUJCNJ
V000002ASDJHWIUJCNJ
V000003ASDJHWIUJCNJ
V000001ASDJHWIUJCNJ
B000001ASDJHWIUJCNJ
B000002ASDJHWIUJCNJ
e questo script
gianluca@gurutech:~$ cat parse.sh
#!/bin/bash
# prendo l'inizio della riga, cerco una lettera e sei cifre
# scarto il resto tengo solo le cifre e le riordino per codici unici
cat test | sed -e "s/^[A-Za-z]\([0-9]\{6\}\).*/\1/" | sort -g | uniq |
while read CODICE; do {
# cerco tutto quello con quel codice e lo butto in un file
cat test | egrep "^[A-Za-z]$CODICE" > cod$CODICE.txt
}
done
ottengo
gianluca@gurutech:~$ cat cod000001.txt
V000001ASDJHWIUJCNJ
V000001ASDJHWIUJCNJ
B000001ASDJHWIUJCNJ
gianluca@gurutech:~$ cat cod000002.txt
V000002ASDJHWIUJCNJ
B000002ASDJHWIUJCNJ
gianluca@gurutech:~$ cat cod000003.txt
V000003ASDJHWIUJCNJ
gurutech> il tuo approccio se il file è grosso è molto lento perchè rifai lo scan del file n+1 volte (dove n è il numero dei codici). dato che tutte le informazioni di cui hai bisogno per "decidere" il file in cui mettere la riga sono contenute nella riga stessa è inutile.
gurutech
22-06-2007, 10:39
gurutech> il tuo approccio se il file è grosso è molto lento perchè rifai lo scan del file n+1 volte (dove n è il numero dei codici). dato che tutte le informazioni di cui hai bisogno per "decidere" il file in cui mettere la riga sono contenute nella riga stessa è inutile.
si ma come dividi? o guardi una riga per volta e con un >> lo appendi di volta in volta a file differenti, oppure guardi l'insieme e prendi il file a blocchi.
io ho scelto l'approccio a blocchi perchè mi pare più veloce.
tu come faresti?
gurutech
22-06-2007, 10:42
non credo che funzioni ... in questo modo non dividi i codici uno dall'altro.
comunque ho detto una cavolata e me ne scuso. l'approccio di Franco2 e' perfettamente funzionante...
DigitalKiller
22-06-2007, 12:21
AAAAh! Certo! Ci sono gli spazi che fanno danno! Prova così:
#!/bin/bash
IFS_BAK=$IFS
IFS=$'\n'
FILE_DI_PARTENZA=$1
for a in $(cat $FILE_DI_PARTENZA)
do
echo $a >> file$(echo $a | cut -c 2-7)
done
IFS=$IFS_BAK
Grande, funziona perfettamente!:D :D
Non credevo fosse così semplice:( Solo non riesco a capire come viene utilizzata la variabile IFS:rolleyes:
Comunque....devo proprio mettermi a studiare un po' di programmazione bash:muro: :D
Grazie per l'aiuto!:D
si ma come dividi? o guardi una riga per volta e con un >> lo appendi di volta in volta a file differenti, oppure guardi l'insieme e prendi il file a blocchi.
io ho scelto l'approccio a blocchi perchè mi pare più veloce.
tu come faresti?
proprio come dici tu, appendendo le righe a file di volta in volta differenti.
penso che come prestazioni sia migliore su file lunghi.
funzionalmente anche la tua soluzione è buona (ma è più da programmatore, non me la sari aspettata da te :D )
Solo non riesco a capire come viene utilizzata la variabile IFS:rolleyes:
IFS è una variabile di sistema che, in pratica, indica per quali caratteri una lista viene divisa nei suoi elementi. Di default è definita dall'"a capo", dallo spazio, dal tab (e forse anche da qualche altra cosa, non ne sono sicuro). Scrivendo IFS=$'\n' gli si dice di considerare la fine dell'elemento solo per l'"a capo".
Poi, con l'ultima riga, lo si reimposta alla definizione standard.
Poi, con l'ultima riga, lo si reimposta alla definizione standard.
sì ma il salvataggio e ripristino del valore non serve a niente, la variabile e' locale allo script e non influenza la shell chiamante.
sì ma il salvataggio e ripristino del valore non serve a niente, la variabile e' locale allo script e non influenza la shell chiamante.
Buono a sapersi, grazie. ;)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.