Problema script

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Problema script

Messaggio da dadante »

Buongiorno a tutti,
Avrei un piccolo problema con il seguente script

Codice: Seleziona tutto

num="$(sed -n '$=' $remove)"
for x in $(seq $num)
  do
    if [ $x -gt $num ]
    then
      break $num
    else
      r=$(sed "$x!d" $remove)
      echo $r
      sed -i "/$r/,+1d" $origin
    fi
done
Sto provando a eliminare delle linee da un file, solo che sed quando va a leggere il file $remove (con le corrispondenze), mi riscrive tutte le volte il file partendo dal file originale, come risultato soltanto le righe con l'ultima corrispondenza vengono eliminare.
Potete aiutarmi?
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

Immagino che il file con le stringhe da rimuovere contenga una stringa per linea.
Se è così, invece di fare un ciclo macchinoso con for, puoi fare un ciclo while che legga una riga per volta.
A parte questo, secondo me il modo più semplice per eliminare certe linee è quello con grep -v.
Inoltre grep, mediante l'opzione -f può usare pattern forniti da un file.
quindi basta:

Codice: Seleziona tutto

grep -v -f "$remove" "$file_da_modificare" > file_risultante.txt
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 13:11
Immagino che il file con le stringhe da rimuovere contenga una stringa per linea.
Se è così, invece di fare un ciclo macchinoso con for, puoi fare un ciclo while che legga una riga per volta.
A parte questo, secondo me il modo più semplice per eliminare certe linee è quello con grep -v.
Inoltre grep, mediante l'opzione -f può usare pattern forniti da un file.
quindi basta:

Codice: Seleziona tutto

grep -v -f "$remove" "$file_da_modificare" > file_risultante.txt
Ciao, ho già provato con il comando cat, ma il file da modificare conta più di 10000 linee.
Ho provato impostando anche export TK_GREP_LINE_MAX=8k (che è il massimo) ma il risultato non cambia
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

dadante ha scritto:
venerdì 27 marzo 2020, 13:47
UbuNuovo ha scritto:
venerdì 27 marzo 2020, 13:11
Immagino che il file con le stringhe da rimuovere contenga una stringa per linea.
Se è così, invece di fare un ciclo macchinoso con for, puoi fare un ciclo while che legga una riga per volta.
A parte questo, secondo me il modo più semplice per eliminare certe linee è quello con grep -v.
Inoltre grep, mediante l'opzione -f può usare pattern forniti da un file.
quindi basta:

Codice: Seleziona tutto

grep -v -f "$remove" "$file_da_modificare" > file_risultante.txt
Ciao, ho già provato con il comando cat, ma il file da modificare conta più di 10000 linee.
Ho provato impostando anche export TK_GREP_LINE_MAX=8k (che è il massimo) ma il risultato non cambia
La soluzione che devo trovare è prendere un range da 1 a 48 (dove 48 sono i mach nel file remove) e processare una riga per volta per poi tornare all'inizio del ciclo:

> riga uno valore PIPPO
Lancio il comando sed
> riga due valore PLUTO
Lancio il comando sed
.....


e via dicendo fino alla quarantottesima riga.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

In generale dovrebbe funzionare, così:

Codice: Seleziona tutto

while read pattern;do
	sed -i "/$pattern/d" "$file_da_modificare"
done < "$remove"
Naturalmente aggiusta il pattern se ce n'è bisogno.
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 14:19
In generale dovrebbe funzionare, così:

Codice: Seleziona tutto

while read pattern;do
	sed -i "/$pattern/d" "$file_da_modificare"
done < "$remove"
Naturalmente aggiusta il pattern se ce n'è bisogno.
Ho già provato questa strada ma non funziona.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

"Non funziona" non mi dice nulla
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 14:43
"Non funziona" non mi dice nulla
Nel senso che va in loop, scrive più volte il file originale.
Il risultato è solo l'ultimo record del file pattern viene scritto (o cancellato in questo caso)
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

Allora hai il pc stregato!
Non ci posso fare nulla.
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 15:13
Allora hai il pc stregato!
Non ci posso fare nulla.
Credo di avere semplicemente un file esageratamente grande per utilizzare semplici comandi :muro:
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

sed non ha problemi a leggere file grandi.
Sapevo che era inutile ma ho provato il codice su di un file con duecentoventimila righe: funziona senza problemi.
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 15:28
sed non ha problemi a leggere file grandi.
Sapevo che era inutile ma ho provato il codice su di un file con duecentoventimila righe: funziona senza problemi.
Hai modo di inviarmi gli esempi utilizzati?
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

Codice: Seleziona tutto

8-) cat remove.txt 
istrice
tacchino
gorilla

8-) cat script.sh 
#!/bin/bash

file_da_modificare='file_grosso.txt'
remove='remove.txt'
while read pattern;do
	sed -i "/$pattern/d" "$file_da_modificare"
done < "$remove"
crei il file grosso con:

Codice: Seleziona tutto

for n in $(seq 1 220000);do 
	echo 'questa è una riga di testo da mantenere bla bla bla blbabla' >> file_grosso.txt
done
quello che segue è il testo con righe da mantenere e da eliminare, lo copi ed incolli in più punti del file_grosso.txt

Codice: Seleziona tutto

8-) cat testo.txt 
questa è una riga contenente cane gatto topo va mantenuta
questa è una riga contenente cane gatto topo istrice va eliminata
questa è una riga contenente cane gatto topo coccodrillo pollo va mantenuta
questa è una riga contenente cane gatto topo pulcino va mantenuta
questa è una riga contenente cane gatto tacchino topo coccodrillo pollo va eliminata
questa è una riga contenente cane gatto topo coccodrillo pollo va mantenuta
questa è una riga contenente cane gatto topo coccodrillo pollo gorilla va eliminata
questa è una riga contenente altro testo e va mantenuta
stessa cosa per questa deve essere mantenuta.
8-) 
poi esegui lo script
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 16:03

Codice: Seleziona tutto

8-) cat remove.txt 
istrice
tacchino
gorilla

8-) cat script.sh 
#!/bin/bash

file_da_modificare='file_grosso.txt'
remove='remove.txt'
while read pattern;do
	sed -i "/$pattern/d" "$file_da_modificare"
done < "$remove"
crei il file grosso con:

Codice: Seleziona tutto

for n in $(seq 1 220000);do 
	echo 'questa è una riga di testo da mantenere bla bla bla blbabla' >> file_grosso.txt
done
quello che segue è il testo con righe da mantenere e da eliminare, lo copi ed incolli in più punti del file_grosso.txt

Codice: Seleziona tutto

8-) cat testo.txt 
questa è una riga contenente cane gatto topo va mantenuta
questa è una riga contenente cane gatto topo istrice va eliminata
questa è una riga contenente cane gatto topo coccodrillo pollo va mantenuta
questa è una riga contenente cane gatto topo pulcino va mantenuta
questa è una riga contenente cane gatto tacchino topo coccodrillo pollo va eliminata
questa è una riga contenente cane gatto topo coccodrillo pollo va mantenuta
questa è una riga contenente cane gatto topo coccodrillo pollo gorilla va eliminata
questa è una riga contenente altro testo e va mantenuta
stessa cosa per questa deve essere mantenuta.
8-) 
poi esegui lo script
Col tuo file nessun problema

Questa è la mia situazione

file_grosso.txt

Codice: Seleziona tutto

#!/bin/bash
for n in $(seq 1 1000);do 
	echo '#EXTINF:-1 file-id="test" file-name="test" file-logo="http://wwww.google.it" group-title="Italia",TEST' >> file_grosso.txt
	echo 'http://stringaesempio1",TEST' >> file_grosso.txt
done
for n in $(seq 1 1000);do 
	echo '#EXTINF:-1 file-id="test" file-name="test" file-logo="http://wwww.google.it" group-title="Brasile",TEST' >> file_grosso.txt
	echo 'http://stringaesempio2",TEST' >> file_grosso.txt
done
for n in $(seq 1 1000);do 
	echo '#EXTINF:-1 file-id="test" file-name="test" file-logo="http://wwww.google.it" group-title="Spagna",TEST' >> file_grosso.txt
	echo 'http://stringaesempio3",TEST' >> file_grosso.txt
done
for n in $(seq 1 1000);do 
	echo '#EXTINF:-1 file-id="test" file-name="test" file-logo="http://wwww.google.it" group-title="Africa",TEST' >> file_grosso.txt
	echo 'http://stringaesempio4",TEST' >> file_grosso.txt
done
for n in $(seq 1 1000);do 
	echo '#EXTINF:-1 file-id="test" file-name="test" file-logo="http://wwww.google.it" group-title="Jamaica",TEST' >> file_grosso.txt
	echo 'http://stringaesempio5",TEST' >> file_grosso.txt
done
for n in $(seq 1 1000);do 
	echo '#EXTINF:-1 file-id="test" file-name="test" file-logo="http://wwww.google.it" group-title="Venezuela",TEST' >> file_grosso.txt
	echo 'http://stringaesempio6",TEST' >> file_grosso.txt
done
for n in $(seq 1 1000);do 
	echo '#EXTINF:-1 file-id="test" file-name="test" file-logo="http://wwww.google.it" group-title="Ucraina",TEST' >> file_grosso.txt
	echo 'http://stringaesempio7",TEST' >> file_grosso.txt
done
remove.txt

Codice: Seleziona tutto

"Africa"
"Venezuela"
"Jamaica"
purtroppo non funziona, come puoi provare rimuove solo Jamaica, ovvero l'ultimo record
Ultima modifica di dadante il venerdì 27 marzo 2020, 16:44, modificato 1 volta in totale.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

Ho dato un'occhiata veloce, non mi pare che ci siano caratteri speciali da farne l'escape, eccetto naturalmente le barre '/'.
In sed usa un altro separatore, per esempio:

Codice: Seleziona tutto

sed -i "@$pattern@d" "$file_da_modificare"
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 16:43
Ho dato un'occhiata veloce, non mi pare che ci siano caratteri speciali da farne l'escape, eccetto naturalmente le barre '/'.
In sed usa un altro separatore, per esempio:

Codice: Seleziona tutto

sed -i "@$pattern@d" "$file_da_modificare"
Provato ma da errore,
usando sed con il comando sostituisci non mi dava problemi.
Provo a studiarmi per bene sed per vedere quali intoppi ci possano essere.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

@dadante A quanto pare nell'espressione a due sole barre non si può cambiare il separatore.
Guarda se trovi qualcosa, altrimenti ti toccherà fare l'escape di tutte barre... oppure... provo un'altra cosa.

Sì,anche i doppi apici danno noia. Con questo codice dovrebbe fungere ma lasciare una riga vuota per ogni cancellazione, se non ci sono problemi puoi cancellare dopo, tutte le righe vuote

Codice: Seleziona tutto

sed -i 's@^.*'$pattern'.*$@@' "$file_da_modificare"
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 17:01
@dadante A quanto pare nell'espressione a due sole barre non si può cambiare il separatore.
Guarda se trovi qualcosa, altrimenti ti toccherà fare l'escape di tutte barre... oppure... provo un'altra cosa.

Sì,anche i doppi apici danno noia. Con questo codice dovrebbe fungere ma lasciare una riga vuota per ogni cancellazione, se non ci sono problemi puoi cancellare dopo, tutte le righe vuote

Codice: Seleziona tutto

sed -i 's@^.*'$pattern'.*$@@' "$file_da_modificare"
Purtroppo nessun risultato.
Provo a vedere il discordo di sed e ti aggiorno!
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: Problema script

Messaggio da UbuNuovo »

Ho provato con i tuoi dati d'esempio e a me funziona, solo che lascia le righe vuote:

Codice: Seleziona tutto

8-) grep -c '^$' file_grosso.txt
3000
che poi posso cancellare con

Codice: Seleziona tutto

8-) sed -i '/^$/d' 'file_grosso.txt'
8-) grep -c '^$' file_grosso.txt
0
Ora mi pare di ricordare che il separatore (diverso da '/') viene riconosciuto da sed perché è dopo per esempio s s///, s@@@ quindi nel nostro caso non viene riconosciuto.

Ps mi funziona anche:

Codice: Seleziona tutto

sed -i 's/^.*'$pattern'.*$//' "$file_da_modificare"
Fermi tutti, mi dispiace non averci pensato prima ma erano solo i doppi apici a dar noia funziona anche la sintassi di cancellazione

Codice: Seleziona tutto

sed -i '/'$pattern'/d' "$file_da_modificare"
script.sh

Codice: Seleziona tutto

#!/bin/bash

file_da_modificare='file_grosso.txt'
remove='remove.txt'
while read pattern;do
	#sed -i "/$pattern/d" "$file_da_modificare"	 		# no!
	#sed -i 's@^.*'$pattern'.*$@@' "$file_da_modificare 	"# si
	#sed -i 's/^.*'$pattern'.*$//' "$file_da_modificare" 	# si
	#sed -i '/'$pattern'/d' "$file_da_modificare" 		# si
	sed -i '/'$pattern'/,+1 d' "$file_da_modificare" 	# elimina anche la riga successiva
done < "$remove"
controllo:

Codice: Seleziona tutto

8-) ./script.sh
8-) grep -E '"Africa"|"Venezuela"|"Jamaica"' file_grosso.txt
8-) grep -c '^$' file_grosso.txt
0
Salva l'Ucraina! 🇺🇦
dadante
Prode Principiante
Messaggi: 11
Iscrizione: venerdì 27 marzo 2020, 11:10
Sesso: Maschile

Re: Problema script

Messaggio da dadante »

UbuNuovo ha scritto:
venerdì 27 marzo 2020, 18:09
Ho provato con i tuoi dati d'esempio e a me funziona, solo che lascia le righe vuote:

Codice: Seleziona tutto

8-) grep -c '^$' file_grosso.txt
3000
che poi posso cancellare con

Codice: Seleziona tutto

8-) sed -i '/^$/d' 'file_grosso.txt'
8-) grep -c '^$' file_grosso.txt
0
Ora mi pare di ricordare che il separatore (diverso da '/') viene riconosciuto da sed perché è dopo per esempio s s///, s@@@ quindi nel nostro caso non viene riconosciuto.

Ps mi funziona anche:

Codice: Seleziona tutto

sed -i 's/^.*'$pattern'.*$//' "$file_da_modificare"
Fermi tutti, mi dispiace non averci pensato prima ma erano solo i doppi apici a dar noia funziona anche la sintassi di cancellazione

Codice: Seleziona tutto

sed -i '/'$pattern'/d' "$file_da_modificare"
script.sh

Codice: Seleziona tutto

#!/bin/bash

file_da_modificare='file_grosso.txt'
remove='remove.txt'
while read pattern;do
	#sed -i "/$pattern/d" "$file_da_modificare"	 		# no!
	#sed -i 's@^.*'$pattern'.*$@@' "$file_da_modificare 	"# si
	#sed -i 's/^.*'$pattern'.*$//' "$file_da_modificare" 	# si
	#sed -i '/'$pattern'/d' "$file_da_modificare" 		# si
	sed -i '/'$pattern'/,+1 d' "$file_da_modificare" 	# elimina anche la riga successiva
done < "$remove"
controllo:

Codice: Seleziona tutto

8-) ./script.sh
8-) grep -E '"Africa"|"Venezuela"|"Jamaica"' file_grosso.txt
8-) grep -c '^$' file_grosso.txt
0
La cosa divertente è che su raspberry (dove ho fatto le prove) non funziona, mentre su Ubuntu x64 si...

Ho modificato sed come segue

Codice: Seleziona tutto

sed -i '/'"$pattern"'/,+1 d' "$origin"
nel file remove originale erano presenti spazi!
mi sono spostato sulla cartella home del raspeberry e ora funziona tutto (e non capisco la causa)

Ad ogni modo grazie mille per il tuo supporto, sei stato disponibilissimo!!
Ultima modifica di dadante il venerdì 27 marzo 2020, 20:01, modificato 1 volta in totale.
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 9 ospiti