/sed/ & VARIABLE script challenge

Fermé
m4ni4k - 8 juin 2009 à 20:11
 m4ni4k - 10 juin 2009 à 18:14
Bonjour,

Je me suis concocté un petit script qui fonctionne honnêtement (en Bourne shell du moins) mais qui est plutôt tiré par les cheveux et qui par conséquent, mérite sont lot de petites retouches.
Voici la chose:
#!/bin/sh
A=/archive.ubuntu.com
read PKG
sudo apt-get update
apt-get -qq --print-uris install $PKG|sed -e 's/'\''//; s/'\''.*//'\
 -e '/ubuntu.com\/u/ s#file:#wget -cNrnH -P'$A' -a'$A'/ubuntu/log_POOL\\\n http:/#'\
 -e '/ubuntu.com\/m/ s#file:'$A'/medibuntu#wget -cNrnH -P'$A'/medibuntu -a'$A'/medibuntu/log_POOL\\\n https://medibuntu.org#%27\
 -e '1i\#!/bin/sh\n'"#  Packages amount:\t\t$(apt-get -qq --print-uris install $PKG|sed -n '$=')"''\
 -e "1i$(sed '/^D/!d;s/^Date: ...,/# /' /var/lib/apt/lists/*ease|sed ':a;$!N;s/\n//;ta')\n"|sed '/^# /{s/UTCDescription: /\t/g;s/#/\n&/g}'\
 >/tmp/apt-wget_$PKG.sh && chmod +x "/tmp/apt-wget_$PKG.sh"

Je vous invite donc à me dire en quoi par exemple je pourrais simplifier les 2 dernières actions de sed.
La première devrait pouvoir me renvoyer plus simplement le nombre de ligne sans devoir rappeler la commande apt-get.
Quant à la seconde, je désespère de devoir aplanir sur une seule ligne le résultat de la substitution de commande sed '/^D/!d;s/^Date: ...,/# /' /var/lib/apt/lists/*ease par un sed ':a;$!N;s/\n//;ta' dans un premier temps, pour la redéployer dans un second temps par un sed '/^# /s/#/\n&/g'.

Accessoirement, j'aimerais également savoir quelle est la manière la plus seyante pour imposer à la commande read, ou plus directement à sa variable PKG, des conditions spécifiques telles que la longueur maximale, l'espacement unique entre chacun des motifs, etc.

En vous remerciant d'avance!
Toute remarque étant bienvenue.

1 réponse

Pour fonctionner aussi bien en bash qu'en pur sh:
#!/bin/bash
A=/archive.ubuntu.com
read PKG
sudo apt-get update
W=`apt-get -qq --print-uris install $PKG`
N=`echo "$W"|sed -n '$='`
D=`sed '/^D/!d;s/^Date: ...,/# /' /var/lib/apt/lists/*ease|sed ':a;$!N;s/\n//;ta'`
echo "$W"|sed -e 's/'\''//; s/'\''.*//'\
 -e "/ubuntu.com\/u/ s#file:#wget -cNrnH -P$A -a$A/ubuntu/log_POOL\\\\\n http:/#"\
 -e "/ubuntu.com\/m/ s#file:$A/medibuntu#wget -cNrnH -P$A/medibuntu -a$A/medibuntu/log_POOL\\\\\n https://medibuntu.org"\
 -e "1i#\!/bin/sh\n#  Packages amount:\t\t$N\n$D\n"|sed '/^# /{s/UTCDescription: /\t/g;s/#/\n&/g}'\
 >/tmp/apt-wget_$PKG.sh && chmod +x "/tmp/apt-wget_$PKG.sh"

Ce qui est plutôt surprenant, c'est que, selon que l'on lance le script en bash ou en sh, le résultat ne sera pas exactement le même.
Essayez vous-même consécutivement en bash puis en sh:
D=`sed '/^D/!d;s/^Date: ...,/# /' /var/lib/apt/lists/*ease|sed ':a;$!N;s/\n//;ta'`;\
echo "$D"|sed '/^# /{s/UTCDescription: /\t/g;s/#/\n&/g}'

L'enseignement à tirer, c'est que de toute évidence, bash et sh n'ont pas la même façon de concevoir le tri!!!
A vrai dire, je ne comprend pas du tout ce que trafique sh!
0
Voici la dernière mouture, qui résout essentiellement le problème des espaces entre les noms des packages.
Ceux-ci seront élégamment remplacés par des tirets au moment de l'écriture du fichier:
#!/bin/bash
A=/archive.ubuntu.com
M=/medibuntu
C="wget -cNrnH -P$A"
H="/log_POOL\\\\\n http:/"
read X
sudo apt-get update
P=`apt-get -qq --print-uris install $X`
Q=`echo "$P"|sed -n '$='`
R=`sed '/^D/!d;s/^Date: ...,/# /' /var/lib/apt/lists/*ease|sed ':a;$!N;s/\n//;ta'`
S=${X// /-}
echo "$P"|sed -e 's/'\''//; s/'\''.*//'\
 -e "/\\$A\/u/ s#file:#$C -a$A/ubuntu$H#"\
 -e "/\\$A\/m/ s#file:$A$M#$C$M -a$A$M$H/packages.medibuntu.org#"\
 -e "1i#\!/bin/sh\n#  Packages amount:\t\t$Q\n$R\n"|sed '/^# /{s/UTCDescription: /\t/g;s/#/\n&/g}'\
 >/tmp/apt-wget_$S.sh && chmod +x /tmp/apt-wget_$S.sh

Fonctionne aussi en sh traditionnel à la nuance près qu'il ne faut pas être trop exigeant sur l'ordre dans lequel les données du repertoire /var/lib/apt/lists/ seront triées
0