Cerca e sostituisci

Postate qui per tutte le discussioni legate a Linux in generale.

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata, la versione del Kernel e magari anche la versione della libreria coinvolta. Questi dati aiutano le persone che possono rispondere.
2) Per evitare confusione prego inserire in questo forum solo topic che riguardano appunto Gnu/Linux in genere, se l'argomento è specifico alla Slackware usate uno dei forum Slackware o Slackware64.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Avatar utente
DaRkO
Linux 0.x
Linux 0.x
Messaggi: 85
Iscritto il: ven 22 apr 2005, 0:00
Località: Roma
Contatta:

Messaggio da DaRkO »

volendo puoi anche usare il perl...ti do un codicillo minimale che potresti modificare a tuo piacimento (e' solo un "plus" alla discussione, perche' hai gia' risolto il problema :) )

Codice: Seleziona tutto

#!/usr/bin/perl -w

use Tie::File;
die "Usage:\n./FileSubst filepath sourcestring deststring" if @ARGV != 3;
tie @file, 'Tie::File', $ARGV[0];
        for (@file) {
                s/$ARGV[1]/$ARGV[2]/g;
        }
untie @file;
Questo e' lo script che uso io, devi solo stare attento a mettere gli escape, ma con qualche modifica potresti sistemartelo bene...se ne avessi voglia, potresti anche implementare il "glob" e fare sostituzioni in piu' file (mi viene in mente un for nel for...)

insomma, libera interpretazione :)

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6643
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Messaggio da targzeta »

Paoletta ha scritto:...e quale sarebbe il problema facendo semplicemente cat $i|sed 's/aaa/bbb/g'> /path/dir/$i?
Succede che ti tronca a zero il file $i.

Come avevo detto nel post precedente, la nuova versione di sed ha ovviato a questo problema introducendo l'opzione -i.
Mi sono dato conferma da solo aggiornando il pacchetto sed con quello della Slackware 10.2!

Spina

Avatar utente
Paoletta
Staff
Staff
Messaggi: 3975
Iscritto il: lun 25 apr 2005, 0:00
Slackware: 14.2 - 64 bit
Desktop: fluxbox
Località: Varese

Messaggio da Paoletta »

ok grazie!

Avatar utente
masalapianta
Iper Master
Iper Master
Messaggi: 2775
Iscritto il: lun 25 lug 2005, 0:00
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian
Località: Roma
Contatta:

Messaggio da masalapianta »

Paoletta ha scritto: e quale sarebbe il problema facendo semplicemente
cat $i|sed 's/aaa/bbb/g'> /path/dir/$i
?
che non funziona dappertutto, ad esempio:

xxx$ uname -a
SunOS xxx 5.9 Generic_118558-06 sun4u sparc SUNW,Sun-Fire-V240
xxx$ cat aaa
ggg ggg ggg
bbbbb bbbbb
cccccccccc
xxx$ cat aaa|sed 's/ggg/aaa/g' > aaa
xxx$ cat aaa
xxx$

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6643
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Messaggio da targzeta »

masalapianta ha scritto: xxx$ cat aaa|sed 's/ggg/aaa/g' > aaa
Non capisco perchè eseguite prima il cat? Per la sintassi della riga di comando di sed:

cat aaa|sed 's/ggg/aaa/g

è semanticamente uguale a

sed 's/ggg/aaa/g' aaa

Spina

Avatar utente
Raistlin84
Linux 3.x
Linux 3.x
Messaggi: 542
Iscritto il: lun 28 mar 2005, 0:00
Località: Pistoia

Messaggio da Raistlin84 »

Scusate non ho ben capito io...
Se volessi aggiungere una stringa a capo dopo un altra come dovrei fare?
Esempio nel file /path/dir/file ho queste le linee:
aaaaaaaa
bbbbbbbb
dddddddd

Se volessi tra la 2° riga e la 3° [che diventerebbe 4° dopo] volessi aggiungere la stringa ccccccc, come potrei fare?

Avatar utente
gallows
Staff
Staff
Messaggi: 3471
Iscritto il: lun 20 set 2004, 0:00
Desktop: cwm
Distribuzione: OpenBSD
Località: ~/
Contatta:

Messaggio da gallows »

Con foo.txt:

Codice: Seleziona tutto

aaaaaaaa
bbbbbbbb
dddddddd

Codice: Seleziona tutto

% sed -i 's/b$/b\ncccccccc/g' foo.txt

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6643
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Messaggio da targzeta »

Raistlin84 ha scritto:...Esempio nel file /path/dir/file ho queste linee:
aaaaaaaa
bbbbbbbb
dddddddd

Se volessi tra la 2° riga e la 3° [che diventerebbe 4° dopo] volessi aggiungere la stringa ccccccc, come potrei fare?
Oltre a quello che ti ha detto giustamente gallows, puoi usare il comando append di sed in questo modo:

sed -i /b/'{a\
> ccccccc
> }' /path/dir/file

Sono tre linee diverse, dopo aver inserito il backslash '\' premi Enter, la shell va a capo e mostra il maggiore '>'.

Quello che fà gallows è sostituire l'ultima b, con una b un a capo e con quello che ti serve (ccccccc). Il comando append è fatto a posta per fare tutto questo. Inoltre c'è anche il comando insert per inserire prima della linea, in questo caso lo si usa così:

sed -i /d/'{i\
> ccccccc
> }' /path/dir/file

Comunque nessuno ti può aiutare meglio di: "man sed".

Spina

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6643
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Messaggio da targzeta »

Paoletta ha scritto:ok grazie!
Se questo "ok grazie!" si riferisce a ciò che ti avevo appena scritto:
Succede che ti tronca a zero il file
farò di più, ti spiegherò perchè lo fa!

Il problema è la shell. In generale:

comando file > file

indica alla shell che l'output del comando deve andare direttamente in file. Ora, la ridirezione come sappiamo è fatta appunto dalla shell, ma come?
Semplice, la shell apre il file e, in questo caso lo tronca a 0 (la ridirezione non è un append >>). Dopo aver aperto il file duplica il suo file descriptor con quello dello standard output. A questo punto, chiude il file descriptor originale del file e manda in esecuzione (tramite la exec) il comando. Dato che i file descriptor sono passati tali e quali ai figli, il comando si trova con il file descriptor 1 (standard output) aperto a quello del file.
Ora, dovè il problema? Bhé, quando la shell ha aperto il file lo ha troncato a 0, quindi il comando non ha più niente da leggere!!!

Spina

Avatar utente
Paoletta
Staff
Staff
Messaggi: 3975
Iscritto il: lun 25 apr 2005, 0:00
Slackware: 14.2 - 64 bit
Desktop: fluxbox
Località: Varese

Messaggio da Paoletta »

caro Spina ti ringrazio della spiegazione...però il fatto che tronchi a 0 il file succede a volte sì ed a volte no (ho fatto degli esperimenti),quindi ci deve essere qualcosa che sfugge...

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6643
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Messaggio da targzeta »

Paoletta ha scritto:... il fatto che tronchi a 0 il file succede a volte sì ed a volte no, ... ci deve essere qualcosa che sfugge
Qualcuna di mia conoscenza direbbe:"Non ci credo neanche se è vero!"

Io comunque ci credo, è possibile che a volte funzioni bene. Se sai riprodurre un caso in cui funzioni tutto bene, prova questo semplice codice:

Codice: Seleziona tutto

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
  return (open("casa.txt",O_TRUNC));
}
Prima scrivi qualcosa in casa.txt e poi esegui il programma compilato. Se quel qualcosa c'è ancora, allora vuol dire che la "open" tronca il file solo se viene scritto qualcosa.

Questa è la prima spiegazione che mi viene in mente.

Spina

P.S. ahh, naturalmente controlla che la open sia stata eseguita correttamente. Ho metti un controllo nel codice, oppure (sotto bash) controlla l'uscita del programma con:

Codice: Seleziona tutto

echo $?
Se è un numero positivo (generalmente 3) allora è andata bene, se è -1 (255) allora è andata male (molto probabilmente il file casa.txt non esiste).

Avatar utente
Paoletta
Staff
Staff
Messaggi: 3975
Iscritto il: lun 25 apr 2005, 0:00
Slackware: 14.2 - 64 bit
Desktop: fluxbox
Località: Varese

Messaggio da Paoletta »

caro spina il tuo ultimo esempio funziona come hai detto tu,ma cat $i|sed 's/aaa/bbb/g'> /path/dir/$i funziona a volte sì e a volte no...perchè non provi anche tu?

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6643
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Messaggio da targzeta »

Paoletta ha scritto:...cat $i| sed 's/aaa/bbb/g'> /path/dir/$i funziona a volte sì e a volte no...
Ma è ovvio!!!

Questa riga di comando è diversa da quella che ti ho spiegato io. cat e sed sono in pipe!!! Quindi dipende se cat ha il tempo di leggere $i prima che la shell lo tronchi!!!
Dato che sono thread diversi, come ben saprai è impossibile predire quale aprirà prima il file (e quindi capita che a volte arrivi prima cat $i, altre volte arrivi prima sed 's/aaa/bbb/g'> /path/dir/$i ).

Ed io che pensavo ci fosse un bug nell'implementazione della open.

Saluti Paoletta
Spina

Avatar utente
Paoletta
Staff
Staff
Messaggi: 3975
Iscritto il: lun 25 apr 2005, 0:00
Slackware: 14.2 - 64 bit
Desktop: fluxbox
Località: Varese

Messaggio da Paoletta »

non credevo che fossero threads, ma che la pipe facesse semplicemente in modo che l'output del primo comando diventasse l'input del secondo...e non mi spiegavo questo comportamento; grazie Spina!

il tutto si capisce meglio guardando qua:
http://it.wikipedia.org/wiki/Pipe

Rispondi