Avec un seul fichier d'entrée contenant uniquement des commentaires (à partir de #) et des lignes de valeur VARIABLE =, est-il possible de remplacer une valeur pour une seule variable si elle est trouvée et, sinon, d'ajouter la paire à la fin du fichier si elle n'est pas trouvée?
Ma méthode actuelle fonctionne en la supprimant lors d'un premier passage, puis en l'ajoutant à la fin du fichier lors d'un second passage, mais cette méthode perturbe l'ordre des lignes (et comporte également deux commandes différentes):
sed -r "/^FOOBAR=.*$/d" -i samefile &&
sed -r "$ a\FOOBAR=newvalue" -i samefile
Est-il possible de le faire, c.-à-d. garder l'ordre de la ligne, dans une seule ligne sed? Si un autre utilitaire (awk, ...) le fait, je le prendrais en charge.
la source
newvalue
est stocké dans une variable?sed "/^${varName}=/{h;s/=.*/=${varValue}/};\${x;/^$/{s//${varName}=${varValue}/;H};x}" ${VARFILE}
avec des variables, des guillemets doubles pour permettre la substitution de variable et$
éviter une substitution qui n’est pas une substitution à ce stade, en plus si votre valeur est stockée dans$$varName
:sed "/^${varName}=/{h;s/=.*/=${!varName}/};\${x;/^$/{s//${varName}=${!varName}/;H};x}" ${VARFILE}
Cela peut probablement être raccourci. Ce n'est pas une seule commande sed et il utilise également grep, mais cela semble être fondamentalement ce que vous voulez. Il s’agit d’une seule ligne et édite le fichier sur place (aucun fichier temporaire).
la source
Voici une
sed
approche plus simple , car je ne trouve passed
hold space
facile de travailler avec. Si vous êtes à l'aise avechold space
, l'approche don_crissti offre une possibilité supplémentaire de conserver quelque chose de la ligne existante, mais cela est généralement très rare.Dans cette approche, il vous suffit d'imprimer toutes les lignes sauf la ligne à supprimer, puis d'ajouter le remplacement à la fin.
la source
Sur la base des autres réponses, si vous voulez remplacer la valeur d'une variable si cette variable est présente dans le fichier et l'ajouter à la fin du fichier si ce n'est pas le cas (ce qui n'est pas le cas de vos
sed
commandes postées ), vous pourrait essayer ceci:la source
C'est un peu plus simple dans awk, bien que l'édition "sur place" ne soit pas automatique:
la source
Utilisez simplement
grep
etecho
pour créer un enregistrement vide:Chaque ligne s'échappe avec le code d'erreur zéro.
la source
grep
etecho
Fonctionne réellement avec ce qui suit:
sed -i '/^FOOBAR=/{h;s/=.*/=newvalue/};${x;/^$/{s//FOOBAR=newvalue/;H};x}' infile
Dans la réponse choisie -i est manquant.la source
faire cela avec perl et in-place ça marche très bien pour moi:
la source
grep
etecho
etperl
au lieu de tout faireperl
? En outre, écrire dans un fichier (>> my.file
) au fur et à mesure que vous le lisez (grep my.file
)?