J'ai un certain nombre de fichiers .conf
qui sont identiques et dans le même répertoire, à l'exception des noms de fichiers différents. Dans chaque fichier .conf
portant un nom unique, j'aimerais remplacer un jeu de caractères dans le fichier par le nom du fichier. Par exemple:
Actuellement dans tous les fichiers:
datafname = example.nex
ofprefix = best.example
Débit idéal:
Nom de fichier: 25.conf
datafname = 25.nex
ofprefix = best.25
Nom de fichier: 26.conf
datafname = 26.nex
ofprefix = best.26
J'ai pensé que je pourrais utiliser sed
pour parcourir tous ces fichiers afin de trouver et remplacer la chaîne de texte par le nom de fichier en utilisant quelque chose comme:
sed -i conf 's/example/echo $f/g' *
mais cela ne fonctionne pas correctement. Quelqu'un pourrait-il avoir une suggestion sur la façon de procéder?
Tu peux faire:
for f in *.conf; do
base=$(basename "$f" '.conf') # gives '25' from '25.conf'
sed -i.before "s/example/$base/g" "$f"
done
Lorsque vous utilisez le commutateur -i
en sed
, vous devez être absolument sûr que votre commande sed
fonctionne car -i
modifie les fichiers in-place. Cela signifie que la sortie générée remplacera le fichier d'entrée. Si votre commande de remplacement (s/…/…/
) est incorrecte, vous risquez de vous retrouver avec des fichiers vides et aucune sauvegarde. J'ai donc utilisé -i.before
qui laissera un fichier *.before
avec le contenu d'origine.
Vous pouvez utiliser une boucle for pour parcourir les fichiers. Utilisez le paramètre expansion pour supprimer l’extension de fichier. Utilisez des guillemets autour de l'expression, sinon la variable ne serait pas développée.
#! /bin/bash
for f in *.conf ; do
b=${f%.conf}
sed -i "s/example/$b/" "$f"
done
Vous pouvez effectuer la tâche sans boucle en utilisant GNU parallel
:
parallel sed -i.old s/example/{.}/ {} ::: *.conf
Ceci est particulièrement utile si vous avez un lot de fichiers à modifier, car parallel
exécute un travail par cœur de la CPU.
-i.old
signifie: éditez le fichier i
name__n-place et faites une sauvegarde en ajoutant l'extension .old
au nom de fichier d'origine (supprimez .old
si vous ne voulez pas de sauvegarde, mais n'oubliez pas que vous n'avez pas de sauvegarde).s/example/{.}/g
signifie s
name__substitute example
avec le nom de fichier en entrée sans son extension ({.}
) et faites-le g
name__lobally (= à chaque occurrence){}
est remplacé par le nom du fichier d'entrée:::
sépare la commande à exécuter des arguments à lui transmettre*.conf
correspond à chaque fichier .conf
du répertoire en coursAvec awk, qui a une variable FILENAME
définie automatiquement sur le nom du fichier (et, si GNU awk, avec des modifications sur place également):
$ for i in {20..26}; do printf "%s\n" "datafname = example.nex" "ofprefix = best.example" > $i.conf; done
$ gawk -i inplace 'FNR == 1 {split(FILENAME, file, ".")} {gsub("example", file[1])} 1' *.conf
$ cat 25.conf
datafname = 25.nex
ofprefix = best.25
FNR == 1 {split(FILENAME, file, ".")}
: sur la première ligne de chaque fichier, divisez le nom de fichier sur .
et stockez-le dans le tableau file
{gsub("example", file[1])} 1
: pour toutes les lignes, remplacez example
par le premier élément du tableau file
et imprimez.