Come altri hanno sottolineato, l'uso di cat o awk invece di un ciclo read-echo è un modo molto migliore per farlo - evita il problema della correzione degli spazi bianchi (e un paio di altri su cui non sei incappato) , corre più veloce, e almeno con cat, è semplicemente un codice più pulito. Ciò nonostante, mi piacerebbe provare a far funzionare correttamente il ciclo di lettura-eco.
In primo luogo, il problema di taglio degli spazi bianchi: il comando di lettura taglia automaticamente gli spazi bianchi iniziali e finali; questo può essere risolto cambiando la sua definizione di spazio bianco impostando la variabile IFS in bianco. Inoltre, read presuppone che un backslash alla fine della riga significhi che la riga successiva è una continuazione e che dovrebbe essere unita insieme a questa; per risolvere questo problema, usa il suo flag -r (raw). Il terzo problema qui è che molte implementazioni di echo interpretano sequenze di escape nella stringa (ad esempio possono trasformarsi in una nuova riga effettiva); per risolvere questo problema, usa invece printf. Infine, proprio come regola generale di igiene dello scripting, non dovresti usare il gatto quando non ne hai realmente bisogno; utilizzare invece il reindirizzamento dell'input. Con queste modifiche, il ciclo interno è simile al seguente:
while IFS='' read -r line; do
printf "%s\n" "$line">>$OUTPUT
done <$f
... ci sono anche un paio di altri problemi con lo script che circonda: la linea che cerca di definire i file come la lista dei file disponibili .textile ha cita intorno ad esso, il che significa che non viene mai espanso in un vero elenco di file.Il modo migliore per farlo è quello di usare un array:
FILES=(../best-practices/*.textile)
...
for f in "${FILES[@]}"
(e tutte le occorrenze di $ f dovrebbe essere tra virgolette nel caso in cui uno qualsiasi dei nomi di file hanno spazi o altri caratteri divertenti in loro - dovrebbe davvero fai questo anche con $ OUTPUT, anche se è definito sicuro nello script.
Infine, c'è uno echo "">$OUTPUT
vicino alla parte superiore dei file loop-over che cancellerà il file di output ogni time through (cioè alla fine, contiene solo l'ultimo file .textile); questo deve essere spostato prima del ciclo. Non sono sicuro se l'intento qui fosse quello di mettere una riga vuota all'inizio del file, o tre righe vuote tra i file (e uno all'inizio e due alla fine), quindi non sono sicuro di cosa sia esattamente la sostituzione appropriata è. Comunque, ecco quello che posso con dopo aver fissato tutti questi problemi:
#!/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
Anche questo uccide lo spazio. Sono passato a riga per riga per vedere se forse mi avrebbe dato più opzioni per salvare lo spazio principale. –
d'oh NON uccide lo spazio bianco. Grazie uomo:> –
Interessante. Questa risposta è stata downvoted due volte senza spiegazione. Se hai intenzione di downvotare, dì perché. (E se è perché stai pensando "questo potrebbe essere solo un comando di gatto": 1. Non proprio, nota le linee vuote in più inserite tra i file e 2. Sto assumendo (forse erroneamente) che questo è stato uno script ridotto per semplicità e la versione reale potrebbe avere qualche logica aggiuntiva per file.) –