Come faccio ad aggiungere testo all'inizio e alla fine di più file di testo in Bash?


24

Ho una directory piena di file di testo. Il mio obiettivo è quello di aggiungere del testo all'inizio e alla fine di tutti. Il testo che va all'inizio e alla fine è lo stesso per ogni file.

Basato sul codice che ho ricevuto dal web, questo è il codice per aggiungere all'inizio del file:

echo -e 'var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)' > $BASEDIR/Translations/Javascript/*.txt

Questo è il codice per aggiungere alla fine del file. L'obiettivo è aggiungere il testo };alla fine di ogni file:

echo "};" >> $BASEDIR/Translations/Javascript/*.txt

Gli esempi da cui ho tratto sono stati per agire su singoli file. Ho pensato di provare a recitare su più file utilizzando il carattere jolly, *.txt.

Potrei fare anche altri errori. In ogni caso, come posso aggiungere testo all'inizio e alla fine di più file?

Risposte:


27

Per anteporre il testo a un file è possibile utilizzare (con l'implementazione GNU di sed):

sed -i '1i some string' file

Aggiungere testo è semplice come

echo 'Some other string' >> file

L'ultima cosa da fare è metterlo in un ciclo che scorre su tutti i file che intendi modificare:

for file in *.txt; do
  sed -i '1i Some string' "$file" &&
  echo 'Some other string' >> "$file"
done

8

Puoi usare GNU sed

Come già illustrato, è possibile inserire righe di testo subito prima e dopo aver abbinato le righe di un file sed, usando rispettivamente il comando ie a. Ciò che non è stato mostrato è che puoi farlo con una riga e per più file contemporaneamente.

Quanto segue inserirà una riga prima della prima 1ie dopo l'ultima riga $a. Gli inserimenti verranno eseguiti per tutti i file corrispondenti al glob *.txt.

sed -i -e '1ivar language = {' -e '$a};' -- *.txt

Entrambi ie anon funzionano solo con i numeri di riga, ma anche su ogni riga che corrisponde a un determinato modello. Ciò inserisce un commento ogni volta che una riga contiene var y = 2;:

sed -i -- '/var y = 2;/i//initialize variable y' *.js

5

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 printfparte del comando da sola, vedrai gli esatti comandi di modifica a cui sta passando ex:

0a
var language = {
.
$a
};
.
x

0asignifica "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 testo dopo l'ultima riga del file.

x significa salvare le modifiche ed uscire.


2

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

L'aggiunta di @ StéphaneChazelas -iinvece di questa sostituzione di file non funziona, stampa solo su stdout.
Oleh Prypin,

@OlehPrypin, davvero il tuo diritto. Commento cancellato
Stéphane Chazelas,

1

Prova a usare ex:

ex -s +'bufdo!1s/^/HEAD/|$s/$/TAIL/' -cxa *.foo

dove sono i comandi:

  • bufdo!esegue i comandi seguenti per ciascun buffer / file aperto (nota: non è POSIX )
  • 1s/^/HEAD/- inserisce il HEADtesto nella prima riga all'inizio della riga
  • $s/$/TAIL/- aggiunge il TAILtesto sull'ultima 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 ( *) con fooestensione, l'uso **/*.foodi ricorsività (dopo abilitazione globstar: shopt -s globstar)


1
@StevenPenny ha ragione. Uso le funzionalità specificate da POSIX solo, personalmente, per le modifiche con script.
Wildcard

1

Con gnu awk, usando l' inplaceestensione e BEGINFILE/ ENDFILE:

gawk -i inplace 'BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1' ./*.txt

1

Ha anche il diritto di essere (con risultati nei .outfile):

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.out' \;

Un'altra variante più elaborata: i file di origine sono stati sostituiti con il risultato:

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}' \; -print

0

Perl one-liner in soccorso:

perl -i -pe'$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof' *.txt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.