Para leer un archivo de texto literalmente, no use plain read
, que procesa la salida de dos maneras:
read
interpreta \
como un personaje de escape; use read -r
para apagar esto.
read
se divide en palabras en caracteres en $IFS
; establecer IFS
en una cadena vacía para desactivar esto.
El idioma habitual para procesar un archivo de texto línea por línea es
while IFS= read -r line; do …
Para obtener una explicación de este idioma, vea ¿Por qué se while IFS= read
usa con tanta frecuencia, en lugar de IFS=; while read..
? .
Para escribir una cadena literalmente, no use simplemente plain echo
, que procesa la cadena de dos maneras:
- En algunos shells, los
echo
procesos escapan de barra invertida. (En bash, depende de si la xpg_echo
opción está configurada).
- Algunas cadenas se tratan como opciones, por ejemplo,
-n
o -e
(el conjunto exacto depende del shell).
Una forma portátil de imprimir una cadena literalmente es con printf
. (No hay mejor manera en bash, a menos que sepa que su entrada no parece una opción echo
). Use el primer formulario para imprimir la cadena exacta y el segundo formulario si desea agregar una nueva línea.
printf %s "$line"
printf '%s\n' "$line"
Esto solo es adecuado para procesar texto , porque:
- La mayoría de los proyectiles se ahogarán con caracteres nulos en la entrada.
- Cuando haya leído la última línea, no tiene forma de saber si había una nueva línea al final o no. (Algunos shells más antiguos pueden tener mayores problemas si la entrada no termina con una nueva línea).
No puede procesar datos binarios en el shell, pero las versiones modernas de utilidades en la mayoría de los dispositivos pueden hacer frente a datos arbitrarios. Para pasar toda la entrada a la salida, use cat
. Ir por una tangente echo -n ''
es una forma complicada y no portátil de no hacer nada; echo -n
sería igual de bueno (o no dependiendo del shell), y :
es más simple y totalmente portátil.
: >| "$file"
cat >>"$file"
o, más simple,
cat >|"$file"
En un script, generalmente no necesita usarlo >|
ya que noclobber
está desactivado de manera predeterminada.