Estoy escribiendo scripts de shell para mi servidor, que es un alojamiento compartido que ejecuta FreeBSD. También quiero poder probarlos localmente, en mi PC con Linux. Por lo tanto, estoy tratando de escribirlos de forma portátil, pero con sed
No veo forma de hacerlo.
Parte de mi sitio web utiliza archivos HTML estáticos generados, y esta línea sed inserta el DOCTYPE correcto después de cada regeneración:
sed -i '1s/^/<!DOCTYPE html> n/' ${file_name.html}
Funciona con GNU sed
en Linux, pero FreeBSD sed
espera el primer argumento después de -i
opción de ser extensión para copia de seguridad. Así es como se vería:
sed -i '' '1s/^/<!DOCTYPE html> n/' ${file_name.html}
Sin embargo, GNU sed
a su vez espera que la expresión siga inmediatamente después de -i
.
(También requiere arreglos con el manejo de nueva línea, pero eso ya está respondido aquí)
Por supuesto que puedo incluir este cambio en la copia de mi servidor del script, pero eso complicaría, es decir, mi uso de VCS para el control de versiones. ¿Hay alguna manera de lograr esto con sed de forma totalmente portátil?
Respuesta aceptada:
GNU sed acepta una extensión opcional después de -i
. La extensión debe estar en el mismo argumento sin espacio intermedio. Esta sintaxis también funciona en BSD sed.
sed -i.bak -e '…' SOMEFILE
Tenga en cuenta que en BSD, -i
también cambia el comportamiento cuando hay varios archivos de entrada:se procesan de forma independiente (por ejemplo, $
coincide con la última línea de cada archivo). Además, esto no funcionará en BusyBox.
Si no desea utilizar archivos de copia de seguridad, puede comprobar qué versión de sed está disponible.
case $(sed --help 2>&1) in
*GNU*) set sed -i;;
*) set sed -i '';;
esac
"[email protected]" -e '…' "$file"
O alternativamente, para evitar aplastar los parámetros posicionales, defina una función.
case $(sed --help 2>&1) in
*GNU*) sed_i () { sed -i "[email protected]"; };;
*) sed_i () { sed -i '' "[email protected]"; };;
esac
sed_i -e '…' "$file"
Si no quiere molestarse, use Perl.
perl -i -pe '…' "$file"
Si desea escribir un script portátil, no use -i
— no está en POSIX. Haz manualmente lo que sed hace debajo del capó:solo es una línea más de código.
sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"