J'ai besoin d'ajouter la ligne suivante à la fin d'un fichier de configuration:
include "/configs/projectname.conf"
dans un fichier nommé lighttpd.conf
Je cherche à utiliser sed
pour le faire, mais je ne vois pas comment.
Comment pourrais-je seulement l'insérer si la ligne n'existe pas déjà?
Restez simple :)
grep + écho devrait suffire:
grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar
-q
Soyez silencieux-x
correspond à toute la ligne-F
le motif est une simple chaîneEdit: suggestions @cerin et @ thijs-wouters incorporées.
Ce serait une solution propre, lisible et réutilisable utilisant grep
et echo
pour ajouter une ligne à un fichier uniquement s'il n'existe pas déjà:
LINE='include "/configs/projectname.conf"'
FILE='lighttpd.conf'
grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE"
Voici une version sed
:
sed -e '\|include "/configs/projectname.conf"|h; ${x;s/incl//;{g;t};a\' -e 'include "/configs/projectname.conf"' -e '}' file
Si votre chaîne est dans une variable:
string='include "/configs/projectname.conf"'
sed -e "\|$string|h; \${x;s|$string||;{g;t};a\\" -e "$string" -e "}" file
Si vous écrivez dans un fichier protégé, les réponses de @drAlberT et @ rubo77 risquent de ne pas fonctionner, car vous ne pouvez pas utiliser Sudo >>
. Une solution simple similaire serait alors d'utiliser tee --append
:
LINE='include "/configs/projectname.conf"'
FILE=lighttpd.conf
grep -qF "$LINE" "$FILE" || echo "$LINE" | Sudo tee --append "$FILE"
Si, un jour, quelqu'un d'autre doit traiter ce code en tant que "code hérité", il vous sera reconnaissant si vous écrivez un code moins exotérique, tel que
grep -q -F 'include "/configs/projectname.conf"' lighttpd.conf
if [ $? -ne 0 ]; then
echo 'include "/configs/projectname.conf"' >> lighttpd.conf
fi
une autre solution sed consiste à toujours l'ajouter à la dernière ligne et à en supprimer une déjà existante.
sed -e '$a\' -e '<your-entry>' -e "/<your-entry-properly-escaped>/d"
"Correctement échappé" signifie mettre une expression rationnelle qui correspond à votre entrée, c’est-à-dire échapper à tous les contrôleurs d’expression rationnelle de votre entrée actuall, c’est-à-dire mettre une barre oblique inverse devant ^ ^//?? + ().
cela pourrait échouer sur la dernière ligne de votre fichier ou s'il n'y a pas de nouvelle ligne enchevêtrée, je n'en suis pas sûre, mais cela pourrait être traité par une branche astucieuse ...
utiliser awk
awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file file
Les réponses utilisant grep sont fausses. Vous devez ajouter une option -x pour faire correspondre toute la ligne, sinon des lignes telles que #text to add
sera toujours identique lorsque vous voudrez ajouter exactement text to add
.
Donc, la solution correcte est quelque chose comme:
grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar
tilisation de sed: Il sera inséré en fin de ligne. Vous pouvez également passer des variables comme d’habitude.
grep -qxF "port=9033" $light.conf
if [ $? -ne 0 ]; then
sed -i "$ a port=9033" $light.conf
else
echo "port=9033 already added"
fi
tilisation de oneliner sed
grep -qxF "port=9033" $lightconf || sed -i "$ a port=9033" $lightconf
tiliser echo peut ne pas fonctionner sous la racine, mais fonctionnera comme ceci. Mais il ne vous laissera pas automatiser les choses si vous cherchez à le faire car il pourrait vous demander un mot de passe.
J'ai eu un problème lorsque j'essayais de modifier à partir de la racine pour un utilisateur particulier. Il suffit d'ajouter le $username
avant était un correctif pour moi.
grep -qxF "port=9033" light.conf
if [ $? -ne 0 ]; then
Sudo -u $user_name echo "port=9033" >> light.conf
else
echo "already there"
fi
J'avais besoin d'éditer un fichier avec des autorisations d'écriture restreintes, donc j'avais besoin de Sudo
. travaillant avec la réponse de ghostdog74 et utilisant un fichier temporaire:
awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file > /tmp/file
Sudo mv /tmp/file file