Como han señalado otros, utilizar cat o awk en lugar de un ciclo de lectura-eco es una forma mucho mejor de hacerlo: evita el problema del recorte del espacio en blanco (y un par de otros con los que no se ha tropezado) , funciona más rápido, y al menos con cat, es simplemente un código más limpio. No obstante, me gustaría intentar conseguir que el ciclo de lectura y eco funcione correctamente.
Primero, el problema de recorte del espacio en blanco: el comando de lectura recorta automáticamente el espacio en blanco inicial y final; esto puede solucionarse cambiando su definición de espacios en blanco al establecer la variable IFS en blanco. Además, read asume que una barra invertida al final de la línea significa que la siguiente línea es una continuación, y debe empalmarse con esta; para arreglar esto, use su indicador -r (raw). El tercer problema aquí es que muchas implementaciones de echo interpretan secuencias de escape en la cadena (por ejemplo, pueden convertir \ n en una nueva línea real); para arreglar esto, use printf en su lugar. Finalmente, al igual que una regla general de higiene de secuencias de comandos, no debe usar cat cuando no lo necesite; use la redirección de entrada en su lugar. Con estos cambios, el bucle interno se ve así:
while IFS='' read -r line; do
printf "%s\n" "$line">>$OUTPUT
done <$f
... también hay un par de problemas con el guión de influencia: la línea que trata de definir los archivos como la lista de archivos disponibles .textile tiene las citas a su alrededor, lo que significa que nunca se expande a una lista real de archivos.La mejor manera de hacer esto es utilizar una matriz:
FILES=(../best-practices/*.textile)
...
for f in "${FILES[@]}"
(y todas las apariciones de $ f debe ser entre comillas dobles en caso de que cualquiera de los nombres de archivo tienen espacios u otros caracteres extraños en ellos - realmente debería hacer esto con $ OUTPUT también, aunque como eso está definido en el script, es realmente seguro dejarlo).
Finalmente, hay un echo "">$OUTPUT
cerca de la parte superior de los bucles sobre archivos que borrará el archivo de salida cada tiempo transcurrido (es decir, al final, solo contiene el último archivo .textile); esto necesita moverse antes del ciclo. No estoy seguro de si la intención aquí fue poner una sola línea en blanco al comienzo del archivo, o tres líneas en blanco entre los archivos (y uno al principio y dos al final), así que no estoy seguro exactamente qué el reemplazo apropiado es De todos modos, esto es lo que puedo con después de fijar todos estos problemas:
#!/bin/sh
OUTPUT="../best_practices.textile"
FILES=(../best-practices/*.textile)
: >"$OUTPUT"
for f in "${FILES[@]}"
do
echo "Processing $f file..."
echo >>"$OUTPUT"
while IFS='' read -r line; do
printf "%s\n" "$line">>"$OUTPUT"
done <"$f"
echo >>"$OUTPUT"
echo >>"$OUTPUT"
done
Eso mata el espacio en blanco también. Cambié a línea por línea para ver si tal vez me daría más opciones para guardar el espacio principal. –
d'oh NO mata el espacio en blanco. Gracias hombre:> –
Interesante. Esta respuesta ha sido downvoted dos veces sin explicación. Si va a downvote, diga por qué. (Y si es porque estás pensando "esto podría ser solo un comando de gato": 1. en realidad no, ten en cuenta las líneas en blanco extra insertadas entre los archivos y 2. Estoy asumiendo (quizás incorrectamente) que este era un script reducido en aras de la simplicidad y la versión real puede tener alguna lógica extra por archivo.) –