Pagina 1 di 2
sed: individuare occorrenze multiple
Inviato: mar 9 nov 2010, 12:46
da ZeroUno
Ho una singola riga in cui dentro ci sono dei blocchetti facilmente intercettabili da una semplice espressione regolare. I blocchetti sono separati da un testo altamente irregolare.
Ho bisogno di una sed che mi elimini tutto questo testo separatore e mi lasci i blocchetti separati da uno spazio o qualcos'altro.
Esempio:
ciao123a-tutti456-help@me789grazie_01
i blocchetti saranno intercettati dall'espressione [0-9]{3}, quindi l'output dovrà essere
123 456 789
ovviamente il testo e i blocchetti sono più complessi, ma l'importante è che per quanto possano essere complessi l'espressione regolare è costruibile. Il numero di occorrenze non è noto a priori.
Ho fatto un po' di prove ma proprio non sono riuscito a venirne a capo.
01
Re: sed: individuare occorrenze multiple
Inviato: mar 9 nov 2010, 13:52
da umaga
ho provato questo semplice grep sulla tua stringa di esempio:
a=ciao123a-tutti456-help@me789grazie_01
echo $a | grep -oe '[0-9][0-9][0-9]'
l'output è stato:
123
456
789
Re: sed: individuare occorrenze multiple
Inviato: mar 9 nov 2010, 14:41
da ZeroUno
ottimo, grazie. Quello che mi stupisce di quella grep è che le entry le restituisce su righe diverse quando si trovano invece tutte sulla stessa riga
Io avevo risolto in un modo un po' più astruso:
1) con sed aggiungi un "|" prima e dopo la regexpa
2) con awk prendi solo i campi $2,$4,$6...
echo ciao123a-tutti456-help@me789grazie_01|sed -r -e 's#/([0-9]{3})#|\1|#ig'|awk -F"|" '{a=2;while($(a)){print $(a);a=a+2}}'
Re: sed: individuare occorrenze multiple
Inviato: mar 9 nov 2010, 16:33
da targzeta
Preferisco anche io grep, se vuoi l'output tra spazi invece che tra newline:
Codice: Seleziona tutto
echo ciao123a-tutti456-help@me789grazie_01|grep -o '[0-9]\{3\}'|tr -s '\n' ' '
Emanuele
Re: sed: individuare occorrenze multiple
Inviato: mer 10 nov 2010, 0:03
da ZeroUno
quel tr fatto così sicuramente mi servirà per qualche cosa (tr non me lo sono mai studiato a fondo così come anche altri) ma per la separazione tra spazi di solito faccio
Codice: Seleziona tutto
echo $(echo ciao123a-tutti456-help@me789grazie_01|grep -o '[0-9]\{3\}')
comunque io ne ho bisogno in un for
Codice: Seleziona tutto
for x in $(echo ciao123a-tutti456-help@me789grazie_01|grep -o '[0-9]\{3\}');do ...
e sicuramente per tutti gli altri tipi di uso di questo caso avrò la convenienza della suddivisione in newline.
A questo putto approfitto per un quesito sul newline. Avendo una lista del tipo
a
b
c
a
d
a
e
f
g
a
h
i
vorrei in output
a b
c
a d
a e
f
g
a h
i
cioè se trovo la stringa 'a' allora unisci con la riga successiva del file (ovviamente 'a' può essere una regex ma è secondario). io risolvevo con una soluzione non proprio performate ma funzionate; qualcosa tipo:
Codice: Seleziona tutto
cat file.txt|while read x;do echo $x|grep -q 'a' &&echo -n "$x "||echo $x;done
nel caso più semplice. questo l'ho abbozzato in questo istante e presenta bug, ma spiega il concetto.
c'è una soluzione più rapida?
Ciao
01
Re: sed: individuare occorrenze multiple
Inviato: mer 10 nov 2010, 9:43
da targzeta
Puoi usare questo:
Emanuele
P.S. Per leggere tutte le righe di un file si può anche usare:
Re: sed: individuare occorrenze multiple
Inviato: gio 11 nov 2010, 13:18
da ZeroUno
spina ha scritto:Puoi usare questo:
Grazie,
P.S. Per leggere tutte le righe di un file si può anche usare:
non si comporta correttamente in caso file.txt contiene spazi.
Re: sed: individuare occorrenze multiple
Inviato: gio 11 nov 2010, 19:13
da targzeta
ZeroUno ha scritto:spina ha scritto:P.S. Per leggere tutte le righe di un file si può anche usare:
non si comporta correttamente in caso file.txt contiene spazi.
Esatto. Per essere più precisi non si comporta bene quando le righe contengono i caratteri dell'IFS che possono essere diversi dal classico:
Quindi basterebbe anche fare un:
ma alla fine forse è meglio usare il comando read come fai tu.
Emanuele
Re: sed: individuare occorrenze multiple
Inviato: ven 12 nov 2010, 13:49
da ZeroUno
spina ha scritto:Quindi basterebbe anche fare un:
ma alla fine forse è meglio usare il comando read come fai tu.
L'unico problema è quando ci deve essere interattività con l'utente:
lista.txt
Codice: Seleziona tutto
dimmi il tuo nome
dimmi il tuo cognome
dimmi la tua età
Codice: Seleziona tutto
cat lista |while read a;do
echo $a
read b
echo $b
done
chiaramente questo codice non funziona.
Re: sed: individuare occorrenze multiple
Inviato: ven 12 nov 2010, 14:26
da targzeta
Sotto questo punto di vista allora è meglio il mio comando. Tra l'altro il tuo comando soffre anche quando un file non ha un '\n' nell'ultima riga:
Codice: Seleziona tutto
$> cat -e lista.txt
dimmi il tuo nome$
dimmi il tuo cognome$
dimmi la tua età
$> cat lista.txt| while read a;do echo $a; done
dimmi il tuo nome
dimmi il tuo cognome
L'errore del '\n' finale non lo si può eliminare dato che è intrinseco al comando 'read' che non trova il fine linea, o almeno io credo che non lo si possa eliminare. Mentre il caso particolare che citavi tu lo si può evitare facendo:
Codice: Seleziona tutto
$> cat lista.txt|while read a;do echo $a; read -u 2 b; echo $b; done
non mi chiedere perchè funziona perchè non lo so, io cercavo di mandare l'output di cat verso lo standard error e mettere in 'a' la lettura dallo stderr. Non ci sono riuscito ma tra le prove ho notato che questo funziona. E' come se tutti e tre i file descriptor siano aperti nella console (infatti funziona anche se al posto di '-u 2' ci metti '-u 1').
Emanuele
Re: sed: individuare occorrenze multiple
Inviato: ven 12 nov 2010, 20:28
da ZeroUno
prima o poi leggerò il man di bash dall'inizio alla fine parola per parola. ogni volta che lo apro scopro una cosa nuova.
spina ha scritto: Tra l'altro il tuo comando soffre anche quando un file non ha un '\n' nell'ultima riga
Ho scritto quel codice al volo direttamente sul forum, senza passarlo per la shell
Ma il caso del mancato eol alla fine del file non l'ho proprio tenuto in considerazione perchè il 99,999% dei miei file ce l'hanno tutti visto che uso vi/vim
il restante 0,001% deriva da quei file volutamente creati con echo -n
Ciao
01
Re: sed: individuare occorrenze multiple
Inviato: sab 13 nov 2010, 16:19
da Mario Vanoni
Codice: Seleziona tutto
[$> cat -e lista.txt
dimmi il tuo nome$
dimmi il tuo cognome$
dimmi la tua età
$
awk '/./ {print} lista.txt
risolve il problema
/./ significa almeno un carattere.
Re: sed: individuare occorrenze multiple
Inviato: ven 26 nov 2010, 15:42
da ZeroUno
Posso sostituire
Codice: Seleziona tutto
awk -F'\n' '{if($1 ~ /^ /){s=s gensub(/^ +/,"",1)}else{print s;s=$1}}END{print s}' nomefile
con qualcosa di più decente?
Per capire cosa fa:
Codice: Seleziona tutto
$ cat nomefile
riga1
riga2
riga3a
riga3b
riga4
riga5a
riga5b
riga6c
riga7
output
Codice: Seleziona tutto
riga1
riga2
riga3ariga3b
riga4
riga5ariga5briga6c
riga7
Re: sed: individuare occorrenze multiple
Inviato: ven 26 nov 2010, 17:10
da Mario Vanoni
ZeroUno ha scritto:Posso sostituire
Codice: Seleziona tutto
awk -F'\n' '{if($1 ~ /^ /){s=s gensub(/^ +/,"",1)}else{print s;s=$1}}END{print s}' nomefile
con qualcosa di più decente?
Per capire cosa fa:
Codice: Seleziona tutto
$ cat nomefile
riga1
riga2
riga3a
riga3b
riga4
riga5a
riga5b
riga6c
riga7
output
Codice: Seleziona tutto
riga1
riga2
riga3ariga3b
riga4
riga5ariga5briga6c
riga7
root@va2:~# awk '/./ {print $1}' nomefile
Codice: Seleziona tutto
riga1
riga2
riga3a
riga3b
riga4
riga5a
riga5b
riga6c
riga7
Re: sed: individuare occorrenze multiple
Inviato: ven 26 nov 2010, 17:23
da targzeta
Non so se ti piace, ma questo (casino) dovrebbe fare la stessa cosa:
Codice: Seleziona tutto
sed -n 'h;:next n;/^ /{H;x;s/\n *//;$b end;x;b next;};x;p;x;:end ${p;q};h;b next' nomefile
Non capisco comunque perchè non ti piace la tua soluzione.
Emanuele