Comment ajouter du texte au début et à la fin de plusieurs fichiers texte dans Bash?

24

J'ai un répertoire plein de fichiers texte. Mon objectif est d'ajouter du texte au début et à la fin de chacun d'eux. Le texte qui va au début et à la fin est le même pour chaque fichier.

Basé sur le code que j'ai obtenu sur le Web, voici le code à ajouter au début du fichier:

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

Il s'agit du code à ajouter à la fin du fichier. Le but est d'ajouter le texte };à la fin de chaque fichier:

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

Les exemples que j'ai tirés étaient pour agir sur des dossiers individuels. Je pensais essayer de jouer sur plusieurs fichiers en utilisant le caractère générique, *.txt.

Je pourrais aussi faire d'autres erreurs. Dans tous les cas, comment ajouter du texte au début et à la fin de plusieurs fichiers?

Questionneur
la source

Réponses:

27

Pour ajouter du texte à un fichier que vous pouvez utiliser (avec l'implémentation GNU de sed):

sed -i '1i some string' file

L'ajout de texte est aussi simple que

echo 'Some other string' >> file

La dernière chose à faire est de mettre cela dans une boucle qui itère sur tous les fichiers que vous souhaitez éditer:

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

Vous pouvez utiliser GNU sed

Comme déjà illustré, vous pouvez insérer des lignes de texte juste avant et après la correspondance des lignes d'un fichier avec sed, en utilisant respectivement la commande iet a. Ce qui n'a pas été montré, c'est que vous pouvez le faire avec une seule ligne et pour plusieurs fichiers à la fois.

Ce qui suit insérera une ligne avant la première 1iet après la dernière ligne $a. Les insertions seront exécutées pour tous les fichiers correspondant au glob *.txt.

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

Les deux iet ane fonctionnent pas seulement avec les numéros de ligne, mais aussi sur chaque ligne qui correspond à un modèle donné. Cela insère un commentaire chaque fois qu'une ligne contient var y = 2;:

sed -i -- '/var y = 2;/i//initialize variable y' *.js
J. Katzwinkel
la source
5

Commande entièrement compatible POSIX, utilisant ex:

for f in *.txt; do printf '%s\n' 0a 'var language = {' . '$a' '};' . x | ex "$f"; done

Si vous exécutez la printfpartie de la commande seule, vous verrez les commandes d'édition exactes qu'elle transmet à ex:

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

0asignifie "Ajouter du texte après la ligne 0" (en d'autres termes, avant la première ligne). La ligne suivante est le texte littéral à "ajouter" après la ligne 0. Le point ( .) sur une ligne termine par lui-même le texte à ajouter .

$a signifie ajouter du texte après la dernière ligne du fichier.

x signifie enregistrer les modifications et quitter.

Caractère générique
la source
2

Voici un moyen de le faire en Perl:

for f in ./*txt; do
  perl -lpe 'BEGIN{print "First string"}END{print "Last string"}' "$f" > foo && 
  mv foo "$f";
done
terdon
la source
@ StéphaneChazelas ajouter -iau lieu de cette substitution de fichier ne fonctionne pas , il s'imprime simplement sur stdout.
Oleh Prypin
@OlehPrypin, en effet votre droit. Commentaire supprimé.
Stéphane Chazelas
1

Essayez d'utiliser ex:

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

où les commandes sont:

  • bufdo!exécute les commandes ci-dessous pour chaque tampon / fichier ouvert (remarque: ce n'est pas POSIX )
  • 1s/^/HEAD/- insère du HEADtexte dans la première ligne au début de la ligne
  • $s/$/TAIL/- ajoute du TAILtexte sur la dernière ligne à la fin de la ligne

et les arguments sont:

  • -s - mode silencieux / rapide
  • -cxa - enregistrez tous les tampons / fichiers ouverts et quittez
  • *.foo- tous les fichiers dans le répertoire courant ( *) avec l' fooextension, l' utilisation **/*.foode récursivité (après l' activation globstar: shopt -s globstar)
kenorb
la source
1
note bufdo n'est pas POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
Steven Penny
1
@StevenPenny a raison. J'utilise les fonctionnalités spécifiées POSIX uniquement, personnellement, pour les modifications par script.
Wildcard
1

Avec gnu awk, en utilisant l' inplaceextension et BEGINFILE/ ENDFILE:

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

A également le droit d'être (avec les résultats dans des .outfichiers):

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

Une autre variante plus élaborée - les fichiers source remplacés par result:

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

Perl one-liner à la rescousse:

perl -i -pe'$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof' *.txt
Kjetil S.
la source