web-dev-qa-db-fra.com

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

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. J'ai pensé que j'essaierais d'agir sur plusieurs fichiers à l'aide du 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?

25
Questioner

Pour ajouter du texte à un fichier, 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 avez l'intention d'éditer:

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

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 i et 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 le premier 1i et 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

i et a ne 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
9
J. Katzwinkel

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 partie printf de la commande seule, vous verrez les commandes d'édition exactes qu'elle transmet à ex:

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

0a signifie "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 le texte à ajouter.

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

x signifie enregistrer les modifications et quitter.

5
Wildcard

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
2
terdon

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

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
1
rook

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

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

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 HEAD texte dans la première ligne au début de la ligne
  • $s/$/TAIL/ - ajoute TAIL texte 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 du répertoire courant (*) avec l'extension foo, utilisez **/*.foo pour la récursivité (après avoir activé globstar: shopt -s globstar)
1
kenorb

Perl one-liner à la rescousse:

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