SED + addition calculation before substitution

Bonjour à toutes et à tous.

Je cherche comment-faire pour calculer avant de remplacer un nombre avec la commande sed.

Par exemple :

Ici j’ai parsé une date par AAAA MM DD et un nombre que je souhaiterais additionner - ce serait le retour \\4

echo 2021092301 | sed -Er 's/^([0-9]{0,4})([0-9]{0,2})([0-9]{0,2})(.*)/'`date +%Y`:\\2:\\3\ \\4'/'
2022:09:23 01

Le retour « normal » pour l’exemple

echo 2021092301 | sed -Er 's/^([0-9]{0,4})([0-9]{0,2})([0-9]{0,2})(.*)/'`date +%Y`\\2\\3`vs=\\4;echo $((vs+1))`'/'
202209235

Prend 4 et ajoute 1 :confused:

echo 2021092301 | sed -Er 's/^([0-9]{0,4})([0-9]{0,2})([0-9]{0,2})(.*)/'`date +%Y`\\2\\3`vs=$4;echo $((vs+1))`'/'
202209231

Ne trouve pas $4 écrit 1

echo 2021092301 | sed -Er 's/^([0-9]{0,4})([0-9]{0,2})([0-9]{0,2})(.*)/'`date +%Y`:\\2:\\3\ $'\\4+1''/'
2022:09:23 01+1

Trouve $'\\4' mais n’additionne pas :confused:


J’ai trouvé cet exemple mais ici c’est toute la chaine :

echo 2021092301 | sed -E 's/^(.*)/echo \$(( & + 3 ))/e'
2021092304

Ce n’est pas cela que je souhaite faire.


Qui pourrait me dire comment-faire ?

Merci à vous.

C’est pour faire un truc du genre mais pas pareil
$ZONE='domain.tld'
$ZONEFILE ='/etc/bind/masters/domain.tld.host'
SERIAL=`/usr/sbin/named-checkzone $ZONE $ZONEFILE | egrep -ho '[0-9]{10}'`
sed (-i) 's/'$SERIAL'/'$(($SERIAL+1))'/' $ZONEFILE

sed -i remplace dans le fichier ATTENTION :slight_smile: Supprimer le -i pour voir la sortie sans modifier le fichier.

:wink:

Salutations,
Romain

J’arrive à faire çà :

# echo $(($(echo "2021092301" | sed -r 's/^([0-9]{0,4})([0-9]{0,2})([0-9]{0,2})(.*)/\1+3/')))
2024
# echo $(($(echo "2021092301" | sed -r 's/^([0-9]{0,4})([0-9]{0,2})([0-9]{0,2})(.*)/\2+3/')))
bash: 09 : valeur trop grande pour la base (le symbole erroné est « 09 »)
# echo $(($(echo "2021092301" | sed -r 's/^([0-9]{0,4})([0-9]{0,2})([0-9]{0,2})(.*)/\3+3/')))
26
# echo $(($(echo "2021092301" | sed -r 's/^([0-9]{0,4})([0-9]{0,2})([0-9]{0,2})(.*)/\4+3/')))
4

Bizarre !

:roll_eyes:

Bonjour

Le shell bash, interprète les valeurs numériques commençant par le chiffre 0 comme des valeurs numériques exprimées en base 8 <=> base octale

michel@deb114x:~$ echo $(( 10 + 1 ))
11
michel@deb114x:~$ 
michel@deb114x:~$ echo $(( 010 + 1 ))
9
michel@deb114x:~$ 
michel@deb114x:~$ echo $(( 20 * 1 ))
20
michel@deb114x:~$ 
michel@deb114x:~$ echo $(( 020 * 1 ))
16
michel@deb114x:~$ 
michel@deb114x:~$ echo $(( 8 * 1 ))
8
michel@deb114x:~$ 
michel@deb114x:~$ echo $(( 08 * 1 ))
bash: 08 : valeur trop grande pour la base (le symbole erroné est « 08 »)
michel@deb114x:~$ 

Bonsoir… essaies bc- l

C’est du m’impo(r)te koi …

Qui me donne une réponse…

Le pourquoi - Hors sujet :)

J’essaie, je veut faire un script pour Let’Encript et plus…

Mon server DNS est propre, il n’pas chez un fournisseur… nsupdate ok//bientôt… -7days - Je n’ai donc pas d’API style acme.sh pour mettre à jour les zone/dns tous les mois (pour DNSSEC et tous les 3 mois pour let’s encrypt - il faut, donc que je parse la date de me zone DNS - entre autre.

ipv10.net | DNSViz

Algorith 13 (ECDSAP256SHA256) c’est mauvais - pas encore apprécié par tous…
https://www.cloudflare.com/fr-fr/dns/dnssec/ecdsa-and-dnssec/

j’ai mis en Algo 8 (RSASHA256) pour les noms de dom courants :face_with_symbols_over_mouth:

DNSSEC Guide — BIND 9 9.18.6 documentation

:frowning:

Avec bash :

michel@deb114x:~$ val=2021092301
michel@deb114x:~$ nbr=${val:8:2}
michel@deb114x:~$ echo "${val:0:4}:${val:4:2}:${val:6:2} $(printf '%02d' $((${nbr#0*} + 1 )))"
2021:09:23 02
michel@deb114x:~$ 
1 J'aime

Merci beaucoup @MicP, bonjour :slight_smile: J’n’suis pas RH :clown_face: :relaxed:

Et si je te demandais,

que je ne sais pas si le nombre est de 1 ou 2 ou 3 ou 4 caractères ou plus :wink: - c’est pour le « tuto » ici-même. Je devrais écrire comment ? Comme cela ?

michel@deb114x:~$ nbr=${val:8:*}

ou michel@deb114x:~$ nbr=${val:8:strlen(val)}

¿ comment compter le nombre de caractères d’une valeur d’une $variable en BASH ? comme strlen en PHP - Merci.

Sinon, je trouve cela plus logique, merci - ok - avec des expressions régulières c’est normal puisque on a « piquer » les 4 premiers caractères, donc, on continue de 0 plus 2 etc… dans la/les parenthèses capturantes :

  1. pour la date de 0 plus 4 caractères
  2. pour le mois de 4 plus 2 caractères.
  3. pour le jour de 6 plus 2 caractères.

Et en plus, pourrais tu m’expliquer le $(printf '%02d') à quoi ou comment on s’en sert.

  • printf ¿ permet de récupérer des valeurs avec % :confused: comment dit-on ; en cache ?
  • %02 ¿ correspond à quoi ?
  • d ¿ correspond à quoi ?
  • ${nbr#0*} ¿ est, doit être la valeur entière (#0) de la variable $nbr dirais-je. Étoile (*) - pourquoi ? :slight_smile:

Merci encore @MicP !

Romain :slight_smile:

Tiens au fait çà me fait penser à cela - UN GROS TRUC QUI FAIT TROP PEUR :star_struck: (en espérant que vous savez çà depuis le début - avant de faire - de commencer l’informatique :confused: :upside_down_face: et de ne pas avoir de fausses données, ou ne pas avoir des statistiques trompeuses etc ^^ :

echo $((145/8*456)) mauvais calcul , retourne 8208 !!
echo 145/8*456 | bc -l calcul correct, retourne 8265.00000000000000000000

ou encore :
echo 12*3.02 | bc -l calcul correct, arrive bien à multiplier avec la virgule, retourne 36.24 .

# echo $((12*3.02))
bash: 12*3.02 : erreur de syntaxe : opérateur arithmétique non valable (le symbole erroné est « .02 »)
Vous avez du nouveau courrier dans /var/mail/root
# echo $((12*3,02))
2

CALCUL FAUX !

apt show bc
...
Description: langage de calculateur de précision arbitraire bc GNU
 GNU bc est un langage algébrique interactif avec une précision arbitraire
 qui suit le standard préliminaire POSIX 1003.2, avec plusieurs extensions
 incluant des noms de variables multicaractères, une instruction « else » et
 des expressions booléennes complètes. GNU bc ne nécessite pas le programme
 séparé GNU dc.

Cordialement,
Romain

IMG20220924151448

NdMoi-même : Je ne sais même plus faire de division sur papier :sob:

:wink:

Super site : http://www.gecif.net :wink: c’est qui ? ici :relaxed:

Super page : linux / #shell : Awk, Sed et Grep

J’aime bien cette ligne :

:wink:

Si on ne sait pas quel est le nombre de caractères qui suivent le 8ème caractère de la chaîne de caractères qui a été assignée comme valeur à la variable nommée nbr, il suffira de ne pas spécifier ce nombre de caractères :

michel@deb114x:~$ val=202109231
michel@deb114x:~$ echo ${val:8}
1
michel@deb114x:~$ 
michel@deb114x:~$ val=20210923000001
michel@deb114x:~$ echo ${val:8}
000001
michel@deb114x:~$ 

michel@deb114x:~$ val=2021092301
michel@deb114x:~$ echo ${#val}
10
michel@deb114x:~$ 
michel@deb114x:~$ val=20210923000001
michel@deb114x:~$ echo ${#val}
14
michel@deb114x:~$ 

Voir le manuel de la commande printf :

man printf

printf '%02d' $valeurDécimaleÀformater

La chaîne de formatage :

  • Compléter avec des zéros
  • Jusqu’à ce que le nombre soit affiché sur deux chiffres
  • La valeur à formater qui est donnée en paramètre est une valeur décimale

${nbr#0*}
C’est tombé en marche dans ce cas précis, mais en fait je me suis trompé,
j’aurais plutôt dû utiliser : ${nbr##+(0)}

<=> supprimer le suite de caractères 0 qui sont au début de la chaîne de caractères qui a été assignée à la variable nommée nbr

michel@deb114x:~$ nbr='000010020345'
michel@deb114x:~$ echo ${nbr##+(0)}
10020345
michel@deb114x:~$ 
michel@deb114x:~$ nbr='aaaaaaxyz'
michel@deb114x:~$ echo ${nbr##+(a)}
xyz
michel@deb114x:~$ 
1 J'aime

C de toi çà … http://www.gecif.net/ merci <3 ou, tu fais exprès …

pardon, oui, donc, le huitième … caractères … oui…

Ah ok…

Ok… décimale comme d et donc, 2 chiffes (décimal, donc :heart_eyes:)…

OK, …pfff… super génial. mme.c.fe je t’aime !

:heartpulse:

Merci pour cette explication #MicP (je met un tag exprès) ;p

Comment s’appelle t’il.elle sur d’autres réseaux sociaux. :rofl:

. (point)

Au fait comment fait-on un point du milieu ?

  • il y a le point médian dont le point de code unicode est U+00B7

  • Il y a celui qui est utilisé en mathématiques comme signe de multiplication
    dont le point de code unicode est U+22C5

  • Il y a la puce typographique dont le point de code unicode est U+2022 qui est souvent utilisée pour structurer des énumérations (comme par exemple les 3 énumérations qui sont dans ce message)


Pour faire s’afficher un caractère en utilisant son point de code unicode,
faire Ctrl+Maj+u et un u (en lettre minuscule) souligné s’affichera
pour nous inviter à entrer la valeur hexadécimale du point de code unicode.
Donc, par exemple, pour faire s’afficher la puce typographique,
il ne restera plus qu’à entrer : 2022


Avec la disposition clavier Français (variante)
on peut faire s’afficher le point milieu utilisé pour la multiplication (U+22C5) en appuyant
simultanément sur la Maj et la touche étoile du pavé numérique : Maj+*

1 J'aime

Okay merci beaucoup @MicP :slight_smile: pour toutes ces explications.

Je cherchais ce type de point -> ·

Faire le point milieu de l’écriture inclusive avec un clavier ?

  • Sur Mac, il est possible d’obtenir le point milieu en faisant la combinaison de touche ALT + MAJ + F.
  • Sur Windows, il faut utiliser la combinaison de touche ALT + 0183. Bref, pas facile… - je n’y arrive pas. Ce n’est pas grave. L’astuce est de faire un copier / coller depuis un texte existant :slight_smile:

Bonne journée à vous.

Encore merci pour ces explications très technique.

C’est le point médian :
celui dont le nom unicode est MIDDLE DOT
celui qui a le point de code unicode U+00B7
et dont l’entité HTML est &#183;


Si besoin, tu pourras retrouver tous les caractères unicode dans cette page web


Si tu utilises l’environnement de bureau XFCE,
tu pourrais lancer, depuis ton compte utilisateur non privilégié
cette ligne de commandes :

echo "keycode  59 = semicolon period semicolon period U00B7 U22C5 U00B7 U22C5" > ~/.Xmodmap

Et après le démarrage suivant de ta session XFCE (<=> Déconnexion… et s’identifier à nouveau),
tu pourras faire s’afficher un point médian en utilisant le raccourci clavier AltGr+;
<=> appuyer sur la touche AltGr
et tout en la maintenant appuyée, appuyer ensuite sur la touche ;

Sinon, il faudra me dire quel est l’environnement de bureau que tu utilises.

1 J'aime

Merci oui d’accord.

Ok merci :slight_smile:

Ok - Merci beaucoup @MicP - Bon dimanche.

Bon dimanche à toi aussi.

1 J'aime

Ok merci - je n’avais pas vu la réponse à ma question.

J’allais dire c’est la même chose pour récupérer le nombre d’arguments dans un script mais ce n’est pas pareil.

Exemple : nano exemple.sh && chmod u+x exemple.sh

#!/bin/sh

echo "$# args in script $(basename ${0})"
echo "${#} args in script $(basename ${0})"
echo "${$#} ???? - script $(basename ${0})"
#echo "${#arg1} ???? - script $(basename ${0})"

echo ""
echo "Pour le fun ;)"
echo "Comment récuperer les args ?"
echo "Premier argument dans la ligne de commande $1"
echo "Deuxième argument dans la ligne de commande $2"
echo ""
echo "Est-ce obligé de faire une boucle et un switch -> case ? Et cela sur (tous) le nombres d'arguments envoyé ?"
echo ""
echo "HS ;)"

Exec :

./exemple.sh arg1=val1 arg2

Output :

2 args in script exemple.sh
2 args in script exemple.sh
19280 ???? - script exemple.sh

Pour le fun ;)
Comment récuperer les args ?
Premier argument dans la ligne de commande arg1=val1
Deuxième argument dans la ligne de commande arg2

Est-ce obligé de faire une boucle et un switch -> case ? Et cela sur (tous) le nombres d'arguments envoyé ?

HS ;)

:wink: