Newsgroup: it.comp.os.linux.iniziare
Titolo: sed e carattere di inizio riga ^

Con riferimento alle mie perplessità (vedi messaggio odierno intitolato "Re:
script shell parsing file csv") riguardo all'effettiva utilità di usare il
carattere di inizio riga nell'espressione...
sed 's/^\([^;]*;[^;]*\);;/\1;TEST;/' prova_temp.csv
... mi sono risposto da solo (vedi oltre) e RINGRAZIO antani, perché con la
sua risposta mi ha spinto a ragionare sulla questione.
Infatti:
dato il file "prova.csv"
------
A;B;C;D;E
F;G;;;;I;L
M;N;O;P;Q
R;S;;U;V
1;2;3
4;5;
6;7;8
9;10;;
------
le operazioni (volte a riempire il ***terzo*** campo quando sia vuoto e
anche quando si trovi a fine riga non terminato da ";")
sed 's/^\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv
       ^
       ^
      notare carattere di inizio riga
e
sed 's/\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv
       ^
       ^
      notare che manca il carattere di inizio riga
prese separatamente si equivalgono, ma...
non appena si fa qualcosa come mettere in pipe due espressioni simili:
sed 's/^\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/^\([^;]*;[^;]*\)
$/\1;TEST;/'
o usarle in un editing sequenziale:
sed -e 's/^\([^;]*;[^;]*\);;/\1;TEST;/' -e 's/^\([^;]*;[^;]*\);$/\1;TEST;/'
prova.csv
ECCO che il CARATTERE di inizio riga FA LA SUA BELLA DIFFERENZA!
Infatti:
sed 's/\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/\([^;]*;[^;]*\)
$/\1;TEST;/'
(che NON usa il carattere si inizio riga)
dà un risultato diverso da
sed 's/^\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/^\([^;]*;[^;]*\)
$/\1;TEST;/'
(che usa il carattere di inizio riga e con cui si ottiene il risultato
voluto)
... e se ci si ragiona un po' sopra, il motivo lo si capisce.
(ricordo che lo scopo dell'uso di sed era scrivere "TEST" nel terzo campo
quando questo fosse vuoto e a prescindere dal fatto che in una riga di soli
tre campi l'ultimo sia terminato da un ";" o meno)
RIPETO che se uso i due comandi separatamente:
sed 's/^\([^;]*;[^;]*\);\(;\|$\)/\1;TEST;/' prova.csv
       ^
       ^
      notare
e
sed 's/\([^;]*;[^;]*\);\(;\|$\)/\1;TEST;/' prova.csv
SI EQUIVALGONO, ma il motivo è ovvio: non sono appunto sequenziali.

 usare il carattere di inizio riga nell'espressione...
La sostanza e' che se non usi ^, allora in una riga del genere
campo1;campo2;campo3;campo4;;;campo7;
verrebbe sostituito il campo 5 con "TEST", perche' l'espressione regolare
non ancorata fa match con "campo3;campo4;;".

ATTENZIONE:
il mio software (KNode), nelle righe che devono essere mandate a capo
(opzione word-wrap in editing) e terminano con ";" elimina il ";"
Quindi, le righe che nel messaggio iniziale di questo thread appaiono come:
        sed 's/^\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/^\([^;]*;[^;]*\)
        $/\1;TEST;/'
        sed 's/\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/\([^;]*;[^;]*\)
        $/\1;TEST;/'
        sed 's/^\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/^\([^;]*;[^;]*\)
        $/\1;TEST;/'
... sono da leggersi così:
sed 's/^\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/^\([^;]*;[^;]*\);$/\1;TEST;/'
                                                                        ^
sed 's/\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/\([^;]*;[^;]*\);$/\1;TEST;/'
                                                                      ^
sed 's/^\([^;]*;[^;]*\);;/\1;TEST;/' prova.csv | sed 's/^\([^;]*;[^;]*\);$/\1;TEST;/'
                                                                        ^