Ho una directory piena di file di testo. Il mio obiettivo è aggiungere del testo allinizio e alla fine di tutti loro. Il testo che va allinizio e alla fine è lo stesso per ogni file.
In base al codice che ho ricevuto dal web, questo è il codice da aggiungere allinizio del file:
echo -e "var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)" > $BASEDIR/Translations/Javascript/*.txt
Questo è il codice da aggiungere alla fine del file. Lobiettivo è aggiungere il testo };
alla fine di ogni file:
echo "};" >> $BASEDIR/Translations/Javascript/*.txt
Gli esempi da cui ho tratto erano per agire su file individuali. Ho pensato di “provare ad agire su più file utilizzando il carattere jolly, *.txt
.
Potrei fare anche altri errori. In ogni caso, come posso aggiungere testo allinizio e alla fine di più file?
Risposta
Per anteporre il testo a un file puoi usare (con il Implementazione GNU di sed
):
sed -i "1i some string" file
Aggiungere del testo è semplice come
echo "Some other string" >> file
Lultima cosa da fare è inserirla in un ciclo che itera su tutti i file che intendi modificare:
for file in *.txt; do sed -i "1i Some string" "$file" && echo "Some other string" >> "$file" done
Risposta
Puoi usare GNU sed
Come già illustrato, puoi inserire righe di testo subito prima e dopo la corrispondenza righe di un file con sed
, utilizzando rispettivamente il comando i
e a
. “Non è stato dimostrato che puoi farlo con una frase e per più file contemporaneamente.
Quanto segue inserirà una riga prima del primo 1i
e dopo lultima riga $a
. Gli inserimenti verranno eseguiti per tutti i file corrispondenti al glob *.txt
.
sed -i -e "1ivar language = {" -e "$a};" -- *.txt
Entrambi i
e a
non funzionano solo con i numeri di riga, ma anche su ogni riga che corrisponde a un determinato modello. Ciò inserirà un commento ogni volta che una riga contiene var y = 2;
:
sed -i -- "/var y = 2;/i//initialize variable y" *.js
Risposta
Comando completamente conforme a POSIX, utilizzando ex
:
for f in *.txt; do printf "%s\n" 0a "var language = {" . "$a" "};" . x | ex "$f"; done
Se esegui la printf
parte del comando da solo, vedrai esattamente i comandi di modifica che sta passando a ex
:
0a var language = { . $a }; . x
0a
significa “Aggiungi testo dopo la riga 0 “(in altre parole, prima della prima riga). La riga successiva è il testo letterale da “aggiungere” dopo la riga 0. Il punto (.
) su una riga da solo termina il testo da aggiungere.
$a
significa aggiungere del testo dopo lultima riga del file.
x
significa salvare le modifiche e uscire .
Risposta
Ecco “un modo per farlo in Perl:
for f in ./*txt; do perl -lpe "BEGIN{print "First string"}END{print "Last string"}" "$f" > foo && mv foo "$f"; done
Commenti
Risposta
ha anche il diritto di essere (con risultati nei file .out
):
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.out" \;
Unaltra variante più elaborata: file di origine sostituiti con il risultato:
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}" \; -print
Risposta
Prova a utilizzare ex
:
ex -s +"bufdo!1s/^/HEAD/|$s/$/TAIL/" -cxa *.foo
dove i comandi sono:
-
bufdo!
esegue i seguenti comandi per ogni buffer / file aperto (nota: “non è POSIX ) -
1s/^/HEAD/
– inserisceHEAD
testo nella prima riga allinizio della riga -
$s/$/TAIL/
– aggiungeTAIL
testo allultima riga alla fine della riga
e gli argomenti sono:
-
-s
– modalità silenziosa / rapida -
-cxa
– salva tutti i buffer / file aperti ed esci -
*.foo
– tutti i file nella directory corrente (*
) confoo
estensione, utilizza**/*.foo
per la ricorsività (dopo aver abilitato globstar:shopt -s globstar
)
Commenti
- nota bufdo non è POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
- @StevenPenny ha ragione. Uso solo le funzionalità specificate da POSIX, personalmente, per le modifiche con script.
Risposta
Con gnu awk
, utilizzando inplace
estensione e BEGINFILE
/ ENDFILE
:
gawk -i inplace "BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1" ./*.txt
Risposta
Perl one-liner in soccorso:
perl -i -pe"$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof" *.txt
-i
invece di questa sostituzione di file non funziona, si stampa solo su stdout.