Pagina 1 di 1
leggere le righe di un file di testo e concatenarle[BASH] RISOLTO
Inviato: mercoledì 10 settembre 2008, 13:03
da leytonn
Ciao a tutti.
Un nuovo problema.
Con un ciclo FOR ottengo una lista di nomi.
ad es....
view_prova_10_what
view_prova_11_what
view_prova_12_what
view_prova_13_what
view_prova_14_what
view_prova_15_what
view_prova_16_what
view_prova_17_what
view_prova_18_what
view_prova_19_what
view_prova_1_what
ora vorrei concatenarle, separate da una vrigola : view_prova_10_what,view_prova_11_what,view_prova_12_what.......
ho provato con head e tail ma non ne vengo fuori.
Inoltre, per complicare la cosa, vorrei che mi concatenasse le stringhe a 10 a 10. Quindi ad es, se ho 33 righe dovrebbe crearmi 3 stringhe da 10 più un'altra da 3.
Come si può fare?
Grazie
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: mercoledì 10 settembre 2008, 13:19
da Demiurgo
Per quanto ne so la cosa più adatta è il comando sed ma non so darti riposte precise, anch'io in quest'ambito sono ancora in fase di studio (b2b)
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: mercoledì 10 settembre 2008, 14:48
da Volans
Puoi usare qualcosa del genere

:
Codice: Seleziona tutto
#!/bin/bash
COUNT=0
LONGLINE=""
while read line
do
LONGLINE="${LONGLINE},${line}"
COUNT=$((${COUNT} + 1))
if [ "${COUNT}" -eq "10" ]
then
echo "${LONGLINE}" | sed s/'^,'/''/ >> NewFile.txt
LONGLINE=""
COUNT=0
fi
done < OldFile.txt
echo "${LONGLINE}" | sed s/'^,'/''/ >> NewFile.txt
exit 0
Unica nota: assicurati che nel file di origine ci sia una riga vuota alla fine, altrimenti perdi l'ultima riga.
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: mercoledì 10 settembre 2008, 15:06
da leytonn
Grazie per la risposta, ho speranza di risolvere.
Aiutami a capire....
Io sono già all'interno di uno script e sono all'interno ci un ciclo for.
Codice: Seleziona tutto
for map in `comando che mi da l'elenco `
do
echo "$map" # e così ottengo la lista precendemente scritta con tutte quelle righe.
Come faccio ora a collegarmi al tuo codice?
Nel frattempo continuo a provarci
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: mercoledì 10 settembre 2008, 16:49
da leytonn
ho fatto un piccolo passo avanti.
Riamanendo sempre il problema del numero massimo di 10, ora ottengo un file di testo fatto ad es. in questo modo
a_what_1 a_what_10 a_what_11 a_what_12 a_what_13 a_what_14 a_what_15 a_what_16 a_what_17 a_what_18 a_what_19 a_what_2 a_what_20 a_what_21 a_what_22 a_what_23 a_what_24 a_what_25 a_what_26 a_what_27 a_what_28 a_what_29 a_what_3 a_what_30 a_what_31 a_what_32 a_what_33 a_what_34 a_what_35 a_what_36 a_what_37 a_what_38 a_what_39 a_what_4 a_what_40 a_what_41 a_what_42 a_what_43 a_what_5 a_what_6 a_what_7 a_what_8 a_what_9
E' possibile eliminare gli spazi e sostituirli con una virgola ? E poi procedere con il tuo codice?
Grazie mille
PS
"a_what_" viene preso da una variabile.
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: mercoledì 10 settembre 2008, 17:09
da Volans
Scusa ma allora basta che inserisci il mio codice al punto giusto...
Codice: Seleziona tutto
COUNT=0
LONGLINE=""
for line in `comando che mi da l'elenco `
do
LONGLINE="${LONGLINE},${line}"
COUNT=$((${COUNT} + 1))
if [ "${COUNT}" -eq "10" ]
then
echo "${LONGLINE}" | sed s/'^,'/''/ >> NewFile.txt
LONGLINE=""
COUNT=0
fi
done
echo "${LONGLINE}" | sed s/'^,'/''/ >> NewFile.txt
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: mercoledì 10 settembre 2008, 19:36
da leytonn
Bueno, mi pare che funzioni.
Mi pare però che va bene fino a 10 parole.
Se sono più di 10, ad esempio 34, come faccio ad ottere 3 stringhe fatte, rispettivamente, dalla prima parola alla decima, dalla undicesima alla ventesima, dalla ventunesimo alla trentesima, e dalla trentunesima alla trentaquattesima?
Grazie
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: mercoledì 10 settembre 2008, 19:39
da Volans
Se "for line in `comando che mi da l'elenco ` " ti reitera 34 volte è esattamente quello che dovrebbe fare, stampa sul file solo ogni 10 e il "resto" che è rimasto dopo il for... (io avevo testato quello di prima)
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: mercoledì 10 settembre 2008, 21:38
da leytonn
Caspiterina direi...funziona benissimo (good)
Ho fatto come hai detto tu
Codice: Seleziona tutto
mv $HOME/NewFile.txt
COUNT=0
LONGLINE=""
for line in `comando che mi da l'elenco `
do
echo "$line"
LONGLINE="${LONGLINE},${line}"
COUNT=$((${COUNT} + 1))
if [ "${COUNT}" -eq "10" ]
then
echo "${LONGLINE}" | sed s/'^,'/''/ >> NewFile.txt
LONGLINE=""
COUNT=0
fi
done
echo "$line"
echo "${LONGLINE}" | sed s/'^,'/''/ >> NewFile.txt
e ottengo il file di testo (se ad es sono 22 parole) così:
a_what_1,a_what_10,a_what_11,a_what_12,a_what_13,a_what_14,a_what_15,a_what_16,a_what_17,a_what_18
a_what_19,a_what_2,a_what_20,a_what_21,a_what_22,a_what_3,a_what_4,a_what_5,a_what_6,a_what_7
a_what_8,a_what_9
Perfetto.
E' giusto eliminare con mv il file di testo creato prima di entrare nel FOR?
Ora ti chiedo, ma ci proverò da domani mattina, come prendere tutte le stringhe delle varie righe del file di testo (in questo caso 3) e passarle a 3 variabili (che saranno poi l'input di un altro comando che dovrò esguire nello script).
Cercherò di capire bene il codice che mi hai postato.
Benissimo.
Grazie tante
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: giovedì 11 settembre 2008, 0:08
da Volans
Il mv iniziale è sintatticamente sbagliato, cosa vorresti fare?
Se è un file temporaneo ti conviene crearlo con un nome dinamico (usando data e ora per esempio) in /tmp e poi cancellarlo dopo.
Anche se il bash non è certo adatto per usare gli array, volendo li potresti usare per evitare di passare attraverso il file esterno temporaneo se il tuo unico scopo è riutilizzare quelle righe come variabili.
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: giovedì 11 settembre 2008, 10:16
da leytonn
Volans ha scritto:
Il mv iniziale è sintatticamente sbagliato, cosa vorresti fare?
Come dovrebbe essere?.
Vorrei evitare che, lanciando più volte lo script, si accodassero nel file di testo più risultati di diverse iterazioni.
Se è un file temporaneo ti conviene crearlo con un nome dinamico (usando data e ora per esempio) in /tmp e poi cancellarlo dopo.
Anche se il bash non è certo adatto per usare gli array, volendo li potresti usare per evitare di passare attraverso il file esterno temporaneo se il tuo unico scopo è riutilizzare quelle righe come variabili.
Si è così, sarebbe meglio riuscire a fare a meno del file di testo. Dovrei usare gli array allora....ci provo.
Sto seguendo i tuoi consigli e provo a utilizzare al posto del file di testo l'orario (non so se è una procedura corretta):
Codice: Seleziona tutto
date > data
ora=` cat data | awk -F " " '{ print $ 4}'`
echo "la variabile da usare è $ora"
#la variabile da usare è per passare le linee del file di testo seguente è l'orario.
#rm $HOME/NewFile.txt
COUNT=0
LONGLINE=""
for line in `comando che mi da l'elenco`
do
echo "$line"
LONGLINE="${LONGLINE},${line}"
COUNT=$((${COUNT} + 1))
if [ "${COUNT}" -eq "10" ]
then
echo "${LONGLINE}" | sed s/'^,'/''/ >> $ora
LONGLINE=""
COUNT=0
fi
done
#
echo "${LONGLINE}" | sed s/'^,'/''/ >> $ora
echo " le righe concatenate sono ....."
cat $ora
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: giovedì 11 settembre 2008, 13:16
da Volans
Per gli array puoi usare qualcosa del genere:
Codice: Seleziona tutto
COUNT=0
LONGLINE=""
declare -a ARRAY
for line in `g.mlist type=rast pattern=$raster2"_"what* `
do
echo "$line"
LONGLINE="${LONGLINE},${line}"
COUNT=$((${COUNT} + 1))
if [ "${COUNT}" -eq "10" ]
then
ARRAY[${#ARRAY[*]}]="`echo "${LONGLINE}" | sed s/'^,'/''/`"
LONGLINE=""
COUNT=0
fi
done
echo "$line"
ARRAY[${#ARRAY[*]}]=`echo "${LONGLINE}" | sed s/'^,'/''/`
Poi per leggere l'array puoi fare in vadi modi, dipende a che ti serve.
Se devi leggerle una per una puoi usare una sintassi del tipo:
Codice: Seleziona tutto
for i in `seq 0 ${#ARRAY[*]}`
do
echo "${ARRAY[${i}]}"
done
P.S. ho visto ora che hai modificato il post precedente mettendo un file con data... se vuoi usare gli array qui sopra trovi come

Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: giovedì 11 settembre 2008, 14:00
da leytonn
Ciao Volans, per timore di fare danni vorrei prima farti vedere una soluzione che sto testando:
Codice: Seleziona tutto
date > data
ora=` cat data | awk -F " " '{ print $ 4}'`
echo "la variabile da usare è $ora"
#la variabile da usare è per passare le linee del file di testo seguente è l'orario.
#rm $HOME/NewFile.txt
COUNT=0
LONGLINE=""
for line in `g.mlist type=rast pattern=$raster2"_"what* `
do
echo "$line"
LONGLINE="${LONGLINE},${line}"
COUNT=$((${COUNT} + 1))
if [ "${COUNT}" -eq "10" ]
then
echo "${LONGLINE}" | sed s/'^,'/''/ >> $ora
LONGLINE=""
COUNT=0
fi
done
#
echo "${LONGLINE}" | sed s/'^,'/''/ >> $ora
echo " le righe concatenate sono ....."
cat $ora
#
num2=`cat $ora |wc -l`
# let "num=num-1"
echo "righe = $num2"
i=1
echo "i=$i"
#
while [ $i -le $num2 ]
do
echo "righe = $num2"
echo "i=$i"
riga$i=` cat $ora | head --lines $i| tail -n 1 `
r.cross input=$riga$i output=$raster2"_"what"_cross"_$i""
i=$((i+1))
done
Tuttavia ottengo un errore strano quando lo script gira
/home/gab/r.visibilità.sh: 228: riga1=a_what_1,a_what_10,a_what_11,a_what_12,a_what_13,a_what_14,a_what_15,a_what_16,a_what_17,a_what_18: not found
e questo-credo-mi compromette il comando successivo.
eppure la riga dovrebbe essere quella.
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: giovedì 11 settembre 2008, 14:36
da Volans
Sinceramente ci sono tante cose migliorerei in questo script, a partire dalle prime due righe (basta che vedi man date) che puoi togliere senz'altro, inoltre se usi gli array non ti serve passare per un file esterno.
Ti consiglio di leggere la pagina wiki sul Bash (link nella barra in alto qui sopra) e anche la
Guida avanzata di scripting Bash 
Re: leggere le righe di un file di testo e concatenarle[BASH]
Inviato: giovedì 11 settembre 2008, 16:37
da leytonn
Funziona!
Dimmi tu quando per una (b2b)
Provo a chiederti un'altra cosa però: ho notato che il ciclo
Codice: Seleziona tutto
for i in `seq 0 ${#ARRAY[*]}`
do
echo "gli array, ossia le righe per r.cross, sono:"
echo "${ARRAY[${i}]}"
r.cross input=${ARRAY[${i}]} output=$raster2"_cross${i}" --overwrite
done
è come se venisse eseguito una volta di più del numero di righe che esamina.
E inoltre, anche se credo che la mia idea è per nulla elegante, mi chiedevo se per rieseguire il comando r.cross (che prende appunto al max 10 parole concatenate) fosse giusto riprendere tutto il discorso degli ARRAY con la nuova lista
N.B. l'elenco delle parole da utilizzare è la lista degli output generati in prima battuta da r.cross.