Sto scrivendo script di shell per il mio server, che è un hosting condiviso che esegue FreeBSD. Voglio anche poterli testare localmente, sul mio PC con Linux. Quindi, sto cercando di scriverli in modo portatile, ma con sed
Non vedo alcun modo per farlo.
Parte del mio sito Web utilizza file HTML statici generati e questa linea sed inserisce DOCTYPE corretto dopo ogni rigenerazione:
sed -i '1s/^/<!DOCTYPE html> n/' ${file_name.html}
Funziona con GNU sed
su Linux, ma FreeBSD sed
si aspetta il primo argomento dopo -i
opzione per essere un'estensione per la copia di backup. Ecco come sarebbe:
sed -i '' '1s/^/<!DOCTYPE html> n/' ${file_name.html}
Tuttavia, GNU sed
a sua volta si aspetta che l'espressione segua immediatamente dopo -i
.
(Richiede anche correzioni con la gestione delle nuove righe, ma è già stata fornita una risposta qui)
Ovviamente posso includere questa modifica nella mia copia del server dello script, ma ciò rovinerebbe, ovvero il mio uso di VCS per il controllo delle versioni. C'è un modo per raggiungere questo obiettivo con sed in un modo completamente portatile?
Risposta accettata:
GNU sed accetta un'estensione opzionale dopo -i
. L'estensione deve essere nello stesso argomento senza spazio intermedio. Questa sintassi funziona anche su BSD sed.
sed -i.bak -e '…' SOMEFILE
Nota che su BSD, -i
cambia anche il comportamento quando sono presenti più file di input:vengono elaborati indipendentemente (quindi ad es. $
corrisponde all'ultima riga di ogni file). Inoltre questo non funzionerà su BusyBox.
Se non vuoi usare i file di backup, puoi controllare quale versione di sed è disponibile.
case $(sed --help 2>&1) in
*GNU*) set sed -i;;
*) set sed -i '';;
esac
"[email protected]" -e '…' "$file"
O in alternativa, per evitare di alterare i parametri posizionali, definire una funzione.
case $(sed --help 2>&1) in
*GNU*) sed_i () { sed -i "[email protected]"; };;
*) sed_i () { sed -i '' "[email protected]"; };;
esac
sed_i -e '…' "$file"
Se non vuoi preoccuparti, usa Perl.
perl -i -pe '…' "$file"
Se vuoi scrivere uno script portatile, non usare -i
— non è in POSIX. Esegui manualmente ciò che sed fa sotto il cofano: è solo un'altra riga di codice.
sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"