Successivo: regexp Estese, Precedente: Altre Risorse, Su: Top [Contenuti][Indice]
Inviare i rapporti sui bug a bug-sed@gnu.org. Includere anche il risultato di ‘sed --version’ nel corpo del messaggio, quando possibile.
Per piacere non inviare rapporti come questo:
while building frobme-1.3.4
$ configure
error→ sed: file sedscr line 1: Unknown option to 's'
Se GNU sed
non configura il vostro pacchetto preferito, dovreste
spendere qualche minuto in più per identificare il problema specifico e
preparare un caso di prova indipendente. A differenza di altri programmi come
i compilatori C, fare casi di prova come questo per sed
è piuttosto
semplice.
Un caso di prova indipendente include tutti i dati necessari per effettuare
la prova, e la specifica invocazione di sed
che causa il problema.
Più piccolo è il caso di prova, e meglio è. Un caso di prova non dovrebbe
riguardare qualcosa di così lontano da sed
come “try to configure
frobme-1.3.4”. Sì, in linea di massima questa è un’informazione
sufficiente per cercare il bug, ma non è una prospettiva molto pratica.
Ora vediamo alcuni bug riportati comunemente che non sono veri e propri bug.
N
sull’ultima rigaLa maggior parte delle versioni di sed
esce senza stampare niente
quando il comando N
è fornito sull’ultima riga di un file.
GNU sed
stampa il pattern space prima di uscire, a meno che naturalmente
non sia stato specificato il flag di comando -n
. Questa
scelta è intenzionale.
Per esempio, il comportamento di
sed N foo bar
dipenderebbe dal numero pari o dispari di righe di
foo12. Oppure, quando si scrive uno script per leggere le
poche righe successive a una corrispondenza trovata, le implementazioni
tradizionali di sed
costringerebbero a scrivere
qualcosa come
/foo/{ $!N; $!N; $!N; $!N; $!N; $!N; $!N; $!N; $!N }
invece del più semplice
/foo/{ N;N;N;N;N;N;N;N;N; }
In ogni caso, l’espediente più semplice è quello di usare $d;N
in
script che fanno affidamento sul comportamento tradizionale, o impostare
la variabile POSIXLY_CORRECT
a un valore non nullo.
sed
usa la sintassi POSIX dell’espressione regolare di base.
Secondo lo standard, il significato di alcune sequenze di protezione in questa
sintassi è indefinito; nel caso di sed
sono rilevanti \|
,
\+
, \?
, \`
, \'
, \<
,
\>
, \b
, \B
, \w
, e \W
.
Come in tutti i programmi GNU che usano le espressioni regolari di
base POSIX, sed
interpreta queste sequenze di protezione come
caratteri speciali. Così, x\+
corrisponde a una o più occorrenze di
‘x’. abc\|def
corrisponde sia ad ‘abc’ che a ‘def’.
Questa sintassi può creare problemi quando si eseguono script scritti per
altre implementazioni di sed
. Alcuni programmi di sed
sono stati scritti col presupposto che \|
e \+
individuano i
caratteri letterali |
e +
. Tali script devono essere
modificati rimuovendo le barre inverse (backslash) spurie se devono essere
usate con le moderne implementazioni di sed
, come
GNU sed
o
GNU sed
.
D’altra parte, alcuni script usano s|abc\|def||g per rimuovere occorrenze
sia di abc
che di def
. Mentre questo funzionava
fino a sed
4.0.x, versioni successive interpretano ciò come
rimozione della stringa abc|def
. Questo è di nuovo un comportamento
indefinito secondo POSIX, e questa interpretazione è
probabilmente più valida: precedenti versioni di sed
, per esempio,
richiedevano l’espressione \/
venisse presa come /
nel caso
comune di protezione della barra obliqua (slash), il che è ancora
un comportamento indefinito; il nuovo comportamento evita questo, ed è una
cosa buona perché il codice che analizza le regexp è solo parzialmente sotto
il nostro controllo.
Inoltre, questa versione di sed
supporta diversi caratteri di
protezione (alcuni dei quali sono multibyte) per inserite negli script
caratteri non stampabili (\a
, \c
, \d
, \o
, \r
,
\t
, \v
, \x
). Questi possono creare problemi simili con
script scritti per altre implementazioni di sed
.
In breve, ‘sed -i’ consente di cancellare il contenuto di un file in sola lettura, e in generale l’opzione -i (vedi Invocazione) consente di sovrascrivere file protetti. Questo non è un bug, ma piuttosto una conseguenza del funzionamento del filesystem Unix.
I permessi di un file ci dicono cosa può accadere ai dati
in quel file, mentre i permessi di una directory ci dicono cosa può
accadere alla lista dei file in quella directory. Con ‘sed -i’
un file già presente sul disco non verrà neppure aperto in scrittura.
Piuttosto, le modifiche verranno fatte su un file temporaneo che alla fine
viene rinominato col nome originale: se si rinominano o eliminano dei file,
si modifica il contenuto della directory, pertanto l’operazione dipende dai
permessi della directory e non del file. Per questa stessa ragione, non è
possibile usare sed
con l’opzione -i su un file
scrivibile che si trova in una directory di sola lettura, e quando su tale
file viene usata l’opzione -i i collegamenti fisici o
simbolici vengono interrotti.
0a
non funziona (dà errore)Non esiste nessuna riga 0. Zero [0] è un indirizzo speciale che è usato solo
per trattare indirizzi come 0,/RE/
come reali all’avvio dello
script: se si scrive 1,/abc/d
e la prima riga include la parola
‘abc’, la corrispondenza viene ignorata perché l’intervallo di
indirizzi deve abbracciare almeno due righe (esclusa la fine del file); ma
ciò che probabilmente si vuole è cancellare ogni riga compresa la
prima, che contiene ‘abc’, e questo si ottiene con 0,/abc/d
.
Successivo: regexp Estese, Precedente: Altre Risorse, Su: Top [Contenuti][Indice]