[BASH] Ricerca grep mantenendo formattazione

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
Boscagoo

[BASH] Ricerca grep mantenendo formattazione

Messaggio da Boscagoo »

Salve a tutti, non riesco a trovare una soluzione ad un problema per un elaborato. Dato un file come questo:

Codice: Seleziona tutto

1:2+2
2:5*8
3:4/7
4:3*2
5:1*85
6:6*6
7:9*8
8:10*1
9:2*8
10:2*3
11:5*9
12:2*5/5
13:3*2*6
dato un pattern inserito da utente (che può essere un numero oppure una espressione aritmetica semplice come + , - , * , /), devo stampare a video il risultato, in ordine inverso di numerazione con il match del pattern. Forse non mi sono spiegato bene...provo con un esempio. Se l'utente inserisce come patter "2", il risultato del mio comando deve essere:

Codice: Seleziona tutto

13:3*2*6
12:2*5/5
10:2*3
9:2*8
4:3*2
1:2+2
Se invece inserisce "+" come pattern da ricercare, il risultato deve essere:

Codice: Seleziona tutto

1:2+2
Il comando che ho provato a scrivere è il seguente:

Codice: Seleziona tutto

sort -nr $session.log | cut -d":" -f2 | grep -n "$pattern"
cioè, inverto la selezione in ordine numerico, considero la seconda parte con il delimintatore ":" e mostro ciò che richiede l'utente.
Il mio problema è la perdita della numerazione tramite il primo cut. Ho provato a guardare sul man se tramite grep posso ricercare da un certo punto in poi senza eliminare il numero progressivo, ma senza successo. Qualcuno sa darmi qualche consiglio? Grazie

M.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

Non ho capito a che ti serve cut; o forse non ti sei spiegato bene.
Per quel che ho capito basta ribaltare la disposizione:

Codice: Seleziona tutto

8-) cat session.log 
1:2+2
2:5*8
3:4/7
4:3*2
5:1*85
6:6*6
7:9*8
8:10*1
9:2*8
10:2*3
11:5*9
12:2*5/5
13:3*2*6

8-) pattern=2
8-) grep "$pattern" session.log | sort -nr
13:3*2*6
12:2*5/5
10:2*3
9:2*8
4:3*2
2:5*8
1:2+2

8-) pattern='+'
8-) grep "$pattern" session.log | sort -nr
1:2+2
8-) 
Salva l'Ucraina! 🇺🇦
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da crap0101 »

secondo me è srot che non gli serve... da quel che ho capito filtrare le linee e poi stamparle in ordine inverso

Codice: Seleziona tutto

crap0101@orange:/tmp/FOO$ cut -d: -f2 < file.txt | grep 2 | tac
3*2*6
2*5/5
2*3
2*8
3*2
2+2
il cut serve perchè - presumo - la prima parte della linea

Codice: Seleziona tutto

NUMERO:
è una specie di indice e non va matchata.
L'output ovviamente sarà diverso da quello dell'esempio del primo post, appunto perchè la prima parte viene tagliata via, nel caso debba essere preservata basta togliere il cut e usare modificare il pattern di grep in modo da tenerne conto.
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

crap0101 [url=http://forum.ubuntu-it.org/viewtopic.php?p=4561791#p4561791][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto: il cut serve perchè - presumo - la prima parte della linea

Codice: Seleziona tutto

NUMERO:
è una specie di indice e non va matchata.
Giusto! non l'avevo proprio considerato.
Se avessi letto con più attenzione gli esempi di output mi sarei reso conto dell'errore :shy: .
Salva l'Ucraina! 🇺🇦
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

Riguardando l'esempio sembra però che debba mantenere il vecchio numero di riga.
In questo caso, senza usare 'grep -P' o 'awk', considerando che studia le 'pipe', potrebbe fare così:

Codice: Seleziona tutto

8-) pattern=2
8-) grep -v "^$pattern:" session.log | grep "$pattern" | tac
13:3*2*6
12:2*5/5
10:2*3
9:2*8
4:3*2
1:2+2

8-) grep -v "^$pattern:" session.log | grep "$pattern" | tac
1:2+2
o con 'sort' al posto di 'tac'

Codice: Seleziona tutto

8-) grep -v "^$pattern:" session.log | grep "$pattern" | sort -nr
13:3*2*6
12:2*5/5
10:2*3
9:2*8
4:3*2
1:2+2
edit: ripensandoci, così va bene solo per il caso specifico, qundi non va bene
Quando ho un po di tempo provo altri metodi.
Salva l'Ucraina! 🇺🇦
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da vaeVictis »

Come suggerito da UbuNuovo, è sicuramente meglio, da un punto di vista delle performance, fare prima il grep e poi il riordinamento.
Se devi semplicemente "ribaltare" l'output, però, conviene usare tac e non sort. Anche nel caso in cui tu usi sort :)
A margine, per eliminare la parte fino ai due punti si può usare anche \K delle espressioni regolari in stile perl, oppure una doppia istruzione per sed.
Non mi dilungo su questo punto, però, perché a parte l'uso di un comando in meno, comporta maneggiare differentemente il "pattern" che si passa.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

Avevo pensato anch'io a \K ma sorge il problema del passare i pattern '+' e '*'
con:

Codice: Seleziona tutto

grep -P "(.*:)\K.*$pattern" session.log | tac

Codice: Seleziona tutto

8-) pattern=2
8-) grep -P "(^.*:)\K.*$pattern" session.log | tac
13:3*2*6
12:2*5/5
10:2*3
9:2*8
4:3*2
1:2+2

8-) pattern='\+'
8-) grep -P "(^.*:)\K.*$pattern" session.log | tac
1:2+2
questo metodo necessita dell'escape di '+' e '*'
quindi ci vorrebbe l'aggiunta del '\' che si potrebbe fare con un if:

Codice: Seleziona tutto

#!/bin/bash
echo 'Inserisci il pattern'
read pattern
if [ "$pattern" = "+" -o "$pattern" =  "*" ] 
	then
		pattern='\'"$pattern"
fi

grep -P "(^.*:)\K.*$pattern" session.log | tac
Ma bisognerebbe sapere cosa può o non può usare: array? File temp? awk? ...
Salva l'Ucraina! 🇺🇦
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da vaeVictis »

Sì, il problema nell'uso di \K è legato alla ricerca "nuda e cruda" di caratteri che nelle espressioni regolari hanno particolari significati.
Per questo dicevo che, se la si usa, bisogna manipolare "con destrezza" le espressioni regolari.

Ovviamente l'utente che usa l'eventuale comando non può "accollarsi" l'onere, quindi andrebbe modificata con una sorta di passaggio intermedio.
Io però non farei un test con -o multipli, perché può diventare troppo lungo.
Mi farei una funzione "isIn" e vedrei se il carattere è interno ad una lista di caratteri problematici.
Il problema è che, usando le espressioni regolari di Perl, temo sia proprio sbagliato ragionare in questi termini... perché anche l'espressione regolare '2+' sarebbe interpretata in modo diverso da quello "letterale".
Pertanto... o si lascia l'onere dell'uso della corretta espressione regolare all'utente... o si spera che esista un "traduttore" di espressioni regolari... ma al momento non mi pare di ricordarmi niente in questo senso.

Se proprio non si vuole usare il cat, credo sia meglio usare sed.
Ma non so quanto sia appropriato parlarne in questa discussione (intendo per le finalità di chi l'ha aperta).
Era solo per dire :)
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

Ora sto facendo altro ma credo che ci sia un metodo che faccia uso di comandi semplici (semmai poco efficienti) e che ora non ci viene in mente.
Altrimenti l'esercizio non mi sembrerebbe adeguato solo all'uso di pipe.
Salva l'Ucraina! 🇺🇦
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

Non dovrei pensarci ma mi è rimasto in capo questo argomento... mi è venuto in mente al volo questo:

Codice: Seleziona tutto

#!/bin/bash
echo 'Inserisci il pattern'
read pattern
risultati=''
while read linea
	do
		indice=$(cut -d: -f1 <(echo "$linea"))
		riga=$(cut -d: -f2 <(echo "$linea"))
		if grep -Fq "$pattern" <(echo "$riga")
			then
				risultati+="$indice:$riga\n"
		fi
done < session.log
tac <(echo -e "$risultati")
Macchinosa ma di semplice comprensione

edit: Oops, mi ero dimenticato che devi usare le pipe

Codice: Seleziona tutto

#!/bin/bash
echo 'Inserisci il pattern'
read pattern
risultati=''
while read linea
	do
		indice=$(echo "$linea" | cut -d: -f1)
		riga=$(echo "$linea" | cut -d: -f2)
		if echo "$riga" | grep -Fq "$pattern"
			then
				risultati+="$indice:$riga\n"
		fi
done < session.log
echo -e "$risultati" | tac
Comunque sono da evitare!
Quando siamo givanissimi (nell'apprendimento di bash) si fa molto uso delle pipe, poi conoscendo tecniche migliori che danno risultati più soddisfacenti si cerca di abbandonale il più possibile. :D
Salva l'Ucraina! 🇺🇦
Boscagoo

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da Boscagoo »

wow, quante risposte...e io sono qui a spaccarmi la testa...allora, facciamo un po' di ordine...allora, io devo mantenere la formattazione, ovvero, il mio output, se il pattern passato è "2" sarebbe quello riportato:

Codice: Seleziona tutto

13:3*2*6
12:2*5/5
10:2*3
9:2*8
4:3*2
1:2+2
quindi, mantenendo il numero di riga. Attenzione però...vorrei fare notare che, se immetto "2", il risultato non deve anche contenere la linea 2! Ho provato il comando suggerito da UbuNuovo funzionerebbe alla grande, ma come detto, se ho una riga nel file come questa:

Codice: Seleziona tutto

6:6*6
non me la mostra. Quindi ho preso in considerazione la soluzione proposta sempre da UbuNuovo , ovvero

Codice: Seleziona tutto

grep -P "(.*:)\K.*$pattern" session.log
ma purtroppo non posso immettere codice Perl o TLC (o come si chiama, non ricordo). So che è soltanto un parametro dato tramite bash normalmente, ma ho paura che durante la presentazione orale...lo considerino come fuori argomento dalla bash (può essere anche no! appunto perchè è solo un paramentro).
Per rispondere a UbuNuovo , posso usare array, file di temp ecc.... ma non script esterni di TLC o Perl o altro, ed è meglio se riesco ad evitare awk e sed e comandi di trattamento output. Vi dico su cosa sta lavorando:

Codice: Seleziona tutto

egrep "[^0-9]*:*$pattern" $session.log
ma prende solo se il primo carretere dopo i : è pattern
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da vaeVictis »

Codice: Seleziona tutto

[^0-9]
Il carattere ^ dovresti metterlo prima della parentesi quadra di apertura :)

Inoltre prima dell'asterisco devi mettere il .

Relativamente all'inserimento di "codice Perl", quello che dovresti inserire non è "codice Perl", ma un'espressione regolare (analoga a quella che stai già usando) ma nella sintassi accettata da Perl :)

p.s.:
Visti i tentativi un po' alla cieca di utilizzare le espressioni regolari sorge spontanea una domanda... dove le stai studiando?
Ultima modifica di vaeVictis il lunedì 14 aprile 2014, 16:23, modificato 1 volta in totale.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Boscagoo

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da Boscagoo »

vaeVictis [url=http://forum.ubuntu-it.org/viewtopic.php?p=4563074#p4563074][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:

Codice: Seleziona tutto

[^0-9]
Il carattere ^ dovresti metterlo prima della parentesi quadra di apertura :)

Relativamente all'inserimento di "codice Perl", quello che dovresti inserire non è "codice Perl", ma un'espressione regolare (analoga a quella che stai già usando) ma nella sintassi accettata da Perl :)
sisi, immagino....ma: aggiornamento: ecco qui

Codice: Seleziona tutto

egrep [0-9]+:.*"$pattern".* $session.log
ma se ricerco con pattern "2+" esplode....dovrei fare in modo che, quando c'è uno dei simboli elementari "+" "-" "*" "/" di mettere il carattere di escape "/" davanti..

M.
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da vaeVictis »

Al momento non ho modo di mettermi a controllare l'espressione regolare.
Ti lascio solo con un consiglio.
L'uso del comando egrep è deprecato.
Si usa il comando grep con l'opzione -E :)

Inoltre, il carattere di escape è \
E i problemi sono relativi a caratteri che in realtà assumono un "significato" particolare nelle espressioni regolari (in questo caso sono più che altro quantificatori).
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

Ti rispondo al volo perché ho da fare altro.
Hai provato lo script con il ciclo while? Non fa uso di comandi esterni o evoluti e mi pare che faccia quello che chiedevi: cerca il pattern solo dopo i due punti mantenendo però l'intera riga in output.
Usa le classiche opzioni di grep: '-q' per non mostrare l'output e '-F' per considerare il pattern letteralmente, quindi puoi inserire '+' o '*' (senza escape), senza che questi vengano espansi. Problema che avresti anche con 'grep -E'.
Salva l'Ucraina! 🇺🇦
Boscagoo

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da Boscagoo »

Chiedo venia, si, il carattere di escape è \ (sto continuando a switchare dalla tastiera italiana a quella americana). si, concordo che egrep è deprecato, ho visto sempre usare solo grep a dire il vero....è anche vero perchè che ci è stato spiegato, quindi lo uso :)
Con grep -e , la sintassi rimane invariata? adesso controllo...anche perchè stavo valutanto di utilizzare il comando tr, in modo da sostituire * con \* e darlo in pasto alla variabile pattern...potrebbe essere una buona idea?
Il ciclo while lo provo....perchè chiedono qualcosa di molto compatto, risolvibile in particolar modo con comandi in pipe.

M.
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da vaeVictis »

Con tr dovresti fare una singola conversione (una pipe) per ogni carattere cui vuoi far precedere lo slash.
Conviene usare sed... anche se sto ancora cercando (nel poco tempo che mi avanza) un programma che magari semplifichi la cosa, ma non lo trovo :)
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

grep -E la 'e' è maiuscola, la sintassi è invariata.
Se fai una funzioncina per "escapare i caratteri problematici" lo script si allunga ugualmente.
Se levi la parte del read che ho messo per comodità per fare le prove, lo script è abbastanza ridotto, e funziona in base ai 'pipe' (vedi la seconda scrittura dello stesso codice)
Salva l'Ucraina! 🇺🇦
Boscagoo

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da Boscagoo »

Codice: Seleziona tutto

cut -d":" -f2 "$session.log" | fgrep -n "$pattern" | sort -r -V
Eccolo qui....con il cut prendo la seconda parte dopo i : messi come separatore, poi con il fgrep cerco il pattern e con il paramentro -n faccio un listato che non viene controllato dalla ricerca del grep e infine rovescio il risutalto...che stupidata!
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4446
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [BASH] Ricerca grep mantenendo formattazione

Messaggio da UbuNuovo »

Davvero!
Bravo, non ricordavo che 'grep -n' utilizzasse i numeri di riga del file di input, pensavo che contasse Le righe in input....
buon per me!

Comunque è meglio se usi 'grep -F' al posto di 'fgrep' e 'tac' al posto di sort.
Salva l'Ucraina! 🇺🇦
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 11 ospiti