/sed/ appel aux puristes!!!

Fermé
m4ni4k - 18 mars 2009 à 01:26
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 - 21 mars 2009 à 11:39
sudo sed -i '/xx:xx:xx:xx:xx:xx/ s/\(NAME="\)\(.*\)\("\)/\1eth\3/' /etc/udev/rules.d/70-persistent-net.rules
sudo sed -i '/xx:xx:xx:xx:xx:xx/ s/NAME=".*"/NAME="eth"/' /etc/udev/rules.d/70-persistent-net.rules

Si ces 2 commandes donneront le même résultat, la première n'est pas très lisible, et la seconde oblige à reprendre le motif NAME=""

Qui dit mieux?!?

8 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
18 mars 2009 à 09:05
Salut,

Je n'ai pas testé ;-) (pas linux au boulot)
sudo sed -i '/\(..:\)\{5\}../ s/\(NAME=\).*/\1"eth"/'
ou si l'option -r est supportée
sudo sed -r -i '/(..:){5}../ s/(NAME=).*/\1"eth"/'
il faut peut être prendre des précautions et sauvegarder l'original avec -i.orig (.orig c'est l'extension, tu peux choisir ce que tu veux)
2
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 896
18 mars 2009 à 09:15
Salut,

Je confirme, ça marche ;-))
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569 > jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020
18 mars 2009 à 09:20
Salut et merci ;-))
0
m4ni4k > lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019
18 mars 2009 à 15:44
Tout d'abord, je tiens à vous remercier tous pour votre participation, et à accorder une mention spéciale à cette brillante jonglerie de la part de lami20j, cependant, l'idée de départ c'est de se concentrer sur la partie de substitution, xx:xx:xx:xx:xx:xx n'étant en réalité qu'une adresse MAC bien spécifique. ;)

Ensuite, toujours dans ce cas précis de remplacement de nom attribué aux périphériques réseaux, par chance le dernier double quote (") se trouve tout à la fin de la ligne, parcqu'en réalité le .*" doit être proscrit dans le cas ou d'autres " seraient présents après le NAME=""

Donc pour l'instant, dans la pratique, la méthode que j'ai retenu, la moins hasardeuse , la plus précise et la plus conforme à ce cas de figure est la suivante ("1f:d9:34:67:45:bd" étant une adresse fictive):


sudo sed -i '/1f:d9:34:67:45:bd/ s/NAME=":alnum:*"/NAME="wlan"/' /etc/udev/rules.d/70-persistent-net.rules


Mais, je ne désespère pas de trouver plus ciblé, quite même à suggérer une adaptation aux développeurs de sed

Je ne me fais pas à l'idée que cette option ne puisse pas exister.
Je touvais déjà assez astucieux l' "&" que j'utilise notamment ici:

sudo sed -i 's/ralt_switch/&,caps:shiftlock/' /etc/X11/xorg.conf

J'aimerais maintenant reprendre cette option, ou du moins m'en inspirer dans des cas plus complexe où l'on veut réutiliser une chaine de caractères à l'exception de certains de ses éléments, qui seraient eux remplacés à la volée.
Ca donnerait un truc du genre:

sudo sed -i '/1f:d9:34:67:45:bd/ s/NAME="\(:alnum:*\)"/\1=wlan/&' /etc/udev/rules.d/70-persistent-net.rules

Si un expert en sed qui maitrise le sujet en connaissant les tenants et aboutissants de la perspective d'une telle adaptation pouvait m'éclairer sur la pertinence de ce type d'adaptation, j'en serais ravi!

a la votre!
0
m4ni4k > m4ni4k
18 mars 2009 à 15:55
petite précision d'affichage de forum

:alnum: est en réalité entre 2 doubles crochets, come ceci [ [:alnum] ]
(mais sans les espaces, que l'on est obliger d'ajouter pour ne pas transformer celui-ci en lien vers www.commentcamarche.net/s/alnum)

sudo sed -i '/xx:xx:xx:xx:xx:xx/ s/NAME="[ [:alnum] ]"/NAME="wlan"/'
0
m4ni4k > m4ni4k
18 mars 2009 à 15:59
rerectification, juste pour le second ":"

sudo sed -i '/xx:xx:xx:xx:xx:xx/ s/NAME="[ [:alnum:] ]"/NAME="wlan"/'
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
18 mars 2009 à 02:10
Salut,
Vaut mieux privilégier la lisibilité ;-).
Une autre solution qui pourrait te convenir :
var='NAME="eth"';
sudo sed -i '/xx:xx:xx:xx:xx:xx/ s/NAME=.*/'$var'/'   /etc/udev/rules.d/70-persistent-net.rules 

Cdlt
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 896
18 mars 2009 à 16:22
Essaye ça :
sed -r '/xx:xx:xx:xx:xx:xx/ s/(NAME=")([^"]*)(".*)/\1CEQUETUVEUX\3/'
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
18 mars 2009 à 17:53
Re,

Il a dit que par chance le dernier double quote (") se trouve tout à la fin de la ligne,

Normalement ([^"]*) dans le pire des cas va avaler tout jusqu'à " qui est en fin de ligne. Pour \3 ne restera rien
Il doit avoir un espace entre le nom de l'interface qu'on veut substituée. En ce cas le " de la fin ne compte plus.
Donc après =" tout sauf " jusqu'au 1er espace (je n'ai pas testé ;-), c'est juste mon p'tit commentaire, puisque je suis chiant ;-))
sed -r '/xx:xx:xx:xx:xx:xx/ s/(NAME=")([^"]*)( .*)/\1CEQUETUVEUX\3/'

0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 896
18 mars 2009 à 18:00
Si tu regardes bien, je n'ai pas englobé le soi disant (dernier ou pas) ' " ' dans le \2, mais dans le \3, de ce fait le \3 contiendra toujours au moins ' " ' et plus si nécessaire...
s/(NAME=")([^"]*)(".*)/\1CEQUETUVEUX\3/'
J'avais testé avant de rendre ma copie ;-))
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
18 mars 2009 à 18:19
sed -r '/xx:xx:xx:xx:xx:xx/ s/(NAME=")([^"]*)( .*)/\1CEQUETUVEUX\3/'
Non, ça ne marchera pas ça. Si tu prends tout sauf le guillemet [^"]*, le caractère suivant est un guillemet et non un espace. Donc, ça ne matchera pas.

L'expression de jipicy est bien correcte.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
18 mars 2009 à 18:06
Re,

contiendra toujours au moins ' " '
Je suis d'accord, mais en ce cas .* est superflue, vu qu'il n'y a rien après "
donc \2 va avaler tout jusqu'au caractère qui est avant " (à la fin de ligne)
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 896
18 mars 2009 à 18:08
Le .* c'est pour faire joli et pis c'est tout ! ;-))
0
m4ni4k > jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020
20 mars 2009 à 17:21
Vous êtes bien gentils les amis, mais en attendant, même si vous avez donné plein de bonnes astuces pour affiner le code de départ, on a pas encore réussi à l'alléger comme je le désirais réellement.

Pour résumer, pour l'instant, ce qui me plait plutôt bien, c'est de faire effectivement comme l'ami20j le suggérait (en tenant compte des petites adaptations à propos du double quote bien entendu) c-à-d:

sed -r 's/(NAME=")([^"]*)(")/\1wlan\3/'
ou
sed 's/NAME="[^"]*"/NAME="wlan"/'

Le [^"] étant déjà bien mieux que l' [ [:alnum:] ]


En partant de là, je suis persuadé qu'il y aurait moyen de faire encore plus ciblé, et que si sed ne le permet pas actuellement, qu'il serait intéressant de le modifier.
C'est la-dessus que j'aimerais bien vous entendre.
Vous n'utilisez jamais l'&???
Et le cas échéant, vous ne vous êtes jamais surpris à imaginer l'utiliser de multiples manières?

Ce serait quand même plus direct et moins générateurs de fautes potentielles de devoir faire à la place de

sed -r 's/(NAME=")([^"]*)(")/\1wlan\3/'
un simple
sed -r 's/NAME="([^"]*)/&wlan/'
0
m4ni4k > m4ni4k
20 mars 2009 à 17:32
J'suis trop con, il suffit de faire ça finalement:

sed -r 's/(NAME=")[^"]*/\1wlan/'

Enfin, encore une fois, ça marche dans ce cas précis, et je m'en satisferai mais je suis sûr que dans d'autres cas de figure, quand il n'y pas de quote, etc., une nouvelle fonctionde sed s'inspirant du & pourrait être d'une aide précieuse.

Bon week-end à tous et encore un grand merci!
0
m4ni4k > m4ni4k
20 mars 2009 à 18:13
Pour tout ceux que ça intéresserait, en pratique ça donne donc ça (notez bien le switch "-ri" qui marche aussi bien que "-r -i" tandis que -ir aboutira à un message d'erreur):

sudo sed -ri '/72:39:ef/ s/(NAME=")[^"]*/\1wlan/' /etc/udev/rules.d/70-persistent-net.rules
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 896 > m4ni4k
20 mars 2009 à 18:36
En partant de là, je suis persuadé qu'il y aurait moyen de faire encore plus ciblé, et que si sed ne le permet pas actuellement, qu'il serait intéressant de le modifier.
C'est la-dessus que j'aimerais bien vous entendre.
Vous n'utilisez jamais l'&???
Et le cas échéant, vous ne vous êtes jamais surpris à imaginer l'utiliser de multiples manières?


Tu t'obstines avec le "&", alors qu'il ne sert qu'à remplacer un motif bien précis, matché par une regex (simple ou complexe), mais facilement isolable et surtout non tributaire de ce qui se trouve avant ou après !!! Ce qui n'est pas le cas de ton problème, conditionné lui par plusieurs facteurs !

Tu voudrais réinventer "sed", mais t'es-tu demandé pourquoi les sous-expressions, les références arrières ou encore les expressions régulières précédentes ont été implémentées par les développeurs de sed ??? Ben pour palier à ce problème justement !
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
20 mars 2009 à 17:45
Salut,

NAME="jlkdsjflsdldlfjds" est toujours à la fin de la ligne?!
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
20 mars 2009 à 18:07
Si t'es sûr que ton fichier se termine par NAME="..." : s/(NAME=").*/\1wlan"/
Sinon il faut reprendre : s/(NAME=")[^"]*(".*)/\1wlan\2/

dans d'autres cas de figure, quand il n'y pas de quote,
Il y a forcément, un caractère délimitant la fin de l'option. Au pire, ça sera l'espace où la virgule. Tu pourras donc t'en servir avec [^,] ou [^ ]
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
20 mars 2009 à 18:17
Re,

Si la ligne se fini toujours avec NAME="............." alors il suffit
sed -r '/(..:){5}../ s/(NAME=").*/\1wlan"/'

J'ai utilise le grep pour afficher seulement les lignes avec modifications
lami20j@debian:~$ rgrep NAME /etc/udev/rules.d/70-persistent-net.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:30:1b:b6:7e:1f", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:30:1b:b6:00:00:7e:83", ATTR{type}=="24", KERNEL=="eth*", NAME="eth1"
lami20j@debian:~$ cat /etc/udev/rules.d/70-persistent-net.rules |sed -r '/(..:){5}../ s/(NAME=").*/\1eth"/' | grep eth
# PCI device 0x10de:0x008c (forcedeth)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:30:1b:b6:7e:1f", ATTR{type}=="1", KERNEL=="eth*", NAME="eth"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:30:1b:b6:00:00:7e:83", ATTR{type}=="24", KERNEL=="eth*", NAME="eth"
lami20j@debian:~$ cat /etc/udev/rules.d/70-persistent-net.rules |sed -r '/(..:){5}../ s/(NAME=").*/\1wlan"/' | grep wlan
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:30:1b:b6:7e:1f", ATTR{type}=="1", KERNEL=="eth*", NAME="wlan"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:30:1b:b6:00:00:7e:83", ATTR{type}=="24", KERNEL=="eth*", NAME="wlan"

0