J'ai beaucoup de mal à obtenir la syntaxe appropriée en utilisant sed
avec des variables contenant un chemin de fichier, un rappel regex et une expression arithmatique. Je ne sais pas comment échapper correctement aux choses.
J'ai un chemin de fichier dans un fichier texte avec un numéro à côté. Je veux trouver cette ligne et incrémenter le nombre.
FILE="/home/username/scripts/test.txt"
LINE="/home/username/Pictures/properties/wallpaper/span/tree.jpg"
sed -i -e "s,'$LINE' \([0-9]*\),'$LINE' $((\1+1))," $FILE
Par exemple..
/home/username/Pictures/properties/wallpaper/span/tree.jpg 2
devraient devenir..
/home/username/Pictures/properties/wallpaper/span/tree.jpg 3
Quelle est la meilleure façon d'échapper au "." dans le chemin du fichier? Comment puis-je implémenter correctement le rappel \1
Et l'expression arithmétique $((\1+1)
?
Actuellement, j'obtiens une mauvaise erreur de jeton \1+1
.
sed
et l'arithmétique ne se mélangent pas. Le bon outil pour des travaux comme celui-ci est awk
.
Considérez ce fichier de test:
$ cat test.txt
/nonmatching/line 1
/home/username/Pictures/properties/wallpaper/span/tree.jpg 2
/another/non/matching/line 5
Nous pouvons incrémenter le numéro de la ligne que vous souhaitez avec:
$ line="/home/username/Pictures/properties/wallpaper/span/tree.jpg"
$ awk -v f="$line" '$0~f {$NF++} 1' test.txt
/nonmatching/line 1
/home/username/Pictures/properties/wallpaper/span/tree.jpg 3
/another/non/matching/line 5
Comme vous pouvez le voir, cela a incrémenté le nombre sur la ligne qui correspondait à $line
.
Une limitation est que ce code, tel qu'il est écrit, ne conservera pas plusieurs blancs sur les lignes pour lesquelles le nombre est incrémenté. Si l'espace est important, nous aurions besoin de plus de définition du format d'entrée.
-v f="$line"
Ceci affecte la valeur de la variable Shell line
à la variable awk f
.
$0~f {$NF++}
Ici, $0~f
est une condition. C'est vrai si la ligne d'entrée, notée $0
, correspond à l'expression régulière f
telle que définie ci-dessus. S'il correspond, l'instruction $NF++
est exécuté. Cela incrémente le dernier champ de la ligne qui, pour votre saisie, est le nombre.
1
C'est le raccourci cryptique d'awk pour imprimer la ligne.
awk
Si vous avez un awk moderne GNU, vous pouvez éditer le fichier en place avec:
gawk -i inplace -v f="$line" '$0~f {$NF++} 1' test.txt
Avec d'autres awks, utilisez:
awk -v f="$line" '$0~f {$NF++} 1' test.txt > tmp.txt && mv -f tmp.txt test.txt
text.txt
s'il n'existe pasDans le cas où le fichier test.txt
is ne contient pas de ligne correspondant à $line
, cette version aura une telle ligne avec 1
comme décompte:
gawk -i inplace -v f="$line" '$0~f {n=1; $NF++} 1; END{if(!n) print f,1>>FILENAME}' test.txt
Ce code ajoute une variable n
. Si $line
est dans le fichier, n
est défini sur 1
. Si ce n'est pas le cas, n
reste à la valeur par défaut de 0
. Au niveau de END
du fichier d'entrée, la valeur de n
est testée. Si n
est toujours nul, la ligne est ajoutée.