J'essaie de modifier mon fichier nginx.conf par programme, qui contient une ligne comme celle-ci:
access_log /var/log/nginx/access.log;
que je veux ressembler à ceci:
access_log /dev/stdout;
Je crois que l'expression régulière ^\s*access_log([^;]*);
capturera la /var/log/nginx/access.log
pièce dans un groupe de capture, mais je ne sais pas comment remplacer correctement le groupe de capture par sed?
J'ai essayé
echo " access_log /var/log/nginx/access.log;" | sed 's/^\s*access_log([^;]*);/\1\\\/dev\\\/stdout/'
mais je reçois l'erreur:
sed: -e expression #1, char 45: invalid reference \1 on `s' command's RHS
si j'essaye sed -r
alors il n'y a pas d'erreur, mais la sortie n'est pas ce que j'attends:
/var/log/nginx/access.log\/dev\/stdout
J'essaie d'être intelligent avec le groupe de capture et ainsi de suite et de ne pas rechercher directement "access_log /var/log/nginx/access.log;" dans le cas où la distribution modifie l'emplacement du fichier journal par défaut.
sed '/access_log/s|/[^;]\+|/dev/stdout|'
Réponses:
Quelques erreurs là-bas.
Tout d'abord, puisque
sed
utilise des expressions régulières de base, vous avez besoin\(
et\)
pour créer un groupe de capture. Le-r
commutateur active les expressions régulières étendues, c'est pourquoi vous n'obtenez pas l'erreur. Voir Pourquoi dois-je échapper des caractères regex dans sed pour être interprétés comme des caractères regex? .Deuxièmement, vous placez le groupe de capture au mauvais endroit. Si je vous comprends bien, vous pouvez le faire:
Notez l'utilisation de
!
délimiteurs en tant que regex pour éviter d'avoir à échapper les barres obliques vers l'intérieur/dev/stdout
.la source
Dans votre expression rationnelle, vous devez savoir que
\No.
c'est la référence arrière au motif entre crochets()
. Donc regexp devrait être's@^(\s*access_log ).*$@\1/dev/stdout/;@'
Je peux offrir
CONSEIL: Que vous ayez l'intention d'utiliser
/
à l'intérieur du motif, vous êtes libre de changers///
pour chaque symbole que vous souhaitezs###
par exemplela source
Plutôt que de le capturer, pourquoi ne pas simplement le trouver et faire une substitution? C'est à dire:
Il recherche les lignes qui correspondent à "
access_log
" puis sur toutes les lignes qui le remplacent, il remplace "/whatever/path/is/there;
" par "/dev/stdout;
"la source