Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

awk: badly formed pattern

17 réponses
Avatar
Hugolino
Bonjour,

Je fais à nouveau appel aux lumières du forum (ma route vers la
connaissance de awk et sed ne dispose pas d'éclairage nocturne :)

Je cherche à réparer une debian/etch dont le root était monté sur une
autre machine dans /mnt/Cassis et depuis laquelle j'ai malheureusement
exécuté un rm -rf /mnt/Cassis/$PZD.

J'ai réussi à recopier les fichiers du package libc6 qui avaient
dégagés, ainsi que toutes les librairies qui provoquait un message
"error while loading shared libraries"
et j'ai fini par pouvoir exécuter:

dpkg --get-selections > pkg-k6

pour avoir la liste de tous les packages du système cassé.
Ce fichier est de la forme:
adduser install
afterstep install
...

J'arrive à faire:

for pkg in $(awk '/lib/ {print $1}' pkg-k6); do echo -n " "$pkg ; done

qui me renvoie bien sur une seule ligne de 2359 octets les 200 packages
de lib à réinstaller.

mais quand je pipe cette commande sur

| aptitude reinstall -

le système
répond "E: Badly formed pattern"

J'ai essayé de bidouiller avec la variable IFS, mais j'ai continué à
avoir la même erreur.


Que dois-je corriger dans ma ligne de commande ?

Plus généralement, n'y aurait-il pas eu plus simple, parce que elle sent
un peu le "Useless Use Of Echo" ?


Evidement puisque je travaille sur un système cassé (dieu merci un ssh
était resté ouvert), on pourra me dire que mon erreur vient de là.

Merci de votre aide


--
Windows: Microsoft's tax on computer illiterates.
Hugo (né il y a 1 367 938 034 secondes)

10 réponses

1 2
Avatar
Benoit Izac
Bonjour,

le 30/08/2007 à 18:37, Hugolino a écrit dans le
message :

dpkg --get-selections > pkg-k6

pour avoir la liste de tous les packages du système cassé.
Ce fichier est de la forme:
adduser install
afterstep install
...

J'arrive à faire:

for pkg in $(awk '/lib/ {print $1}' pkg-k6); do echo -n " "$pkg ; done

qui me renvoie bien sur une seule ligne de 2359 octets les 200 packages
de lib à réinstaller.

mais quand je pipe cette commande sur

| aptitude reinstall -

le système
répond "E: Badly formed pattern"

J'ai essayé de bidouiller avec la variable IFS, mais j'ai continué à
avoir la même erreur.


Que dois-je corriger dans ma ligne de commande ?


Tu ne passes pas les noms des paquets en arguments de aptitude reinstall
mais sur l'entrée standard.

awk 'BEGIN{printf "aptitude reinstall"}
/lib/ {printf " "$1}
END{printf "n"}' pkg-k6 | sh

Tu peux remplacer « sh » par « cat » pour voir la commande avant.

--
Benoit Izac

Avatar
Hugolino
Le Thu, 30 Aug 2007 23:04:45 +0200, Benoit Izac a écrit:
le 30/08/2007 à 18:37, Hugolino a écrit dans le
pour avoir la liste de tous les packages du système cassé.
Ce fichier est de la forme:
adduser install
...

J'arrive à faire:
for pkg in $(awk '/lib/ {print $1}' pkg-k6); do echo -n " "$pkg ; done
qui me renvoie bien sur une seule ligne de 2359 octets les 200 packages
de lib à réinstaller.

mais quand je pipe cette commande sur
| aptitude reinstall -
le système répond "E: Badly formed pattern"

Que dois-je corriger dans ma ligne de commande ?


Tu ne passes pas les noms des paquets en arguments de aptitude reinstall
mais sur l'entrée standard.


<soupir>C'est ça que je comprendrais jamais</soupir>

Je croyais bien envoyer la sortie de 'for pkg...' sur l'entrée
standard de 'aptitude reinstall'.
Mais où l'envoyé-je en fait ? Qu'elle était mon erreur exactement ?

awk 'BEGIN{printf "aptitude reinstall"}
/lib/ {printf " "$1}
END{printf "n"}' pkg-k6 | sh

Tu peux remplacer « sh » par « cat » pour voir la commande avant.


OK, ça marche mais finalement j'avais déjà lancé:
for pkg in $(grep '^lib' pkg-k6 | cut -f1);do aptitude reinstall $pkg;done

Ce qui a été extrêmement couteux puisque aptitude se relance à chaque fois.

Merci de ton aide


--
Procédons par étapes.
Allons bon. Je sens encore venir une belle explication à destination des

pauvres ploucs qui n'entravent rien à la logique totogonale.
Hugo (né il y a 1 367 948 296 secondes)


Avatar
Benoit Izac
Bonjour,

le 31/08/2007 à 01:42, Hugolino a écrit dans le
message :

mais quand je pipe cette commande sur
| aptitude reinstall -
le système répond "E: Badly formed pattern"

Que dois-je corriger dans ma ligne de commande ?


Tu ne passes pas les noms des paquets en arguments de aptitude
reinstall mais sur l'entrée standard.


<soupir>C'est ça que je comprendrais jamais</soupir>

Je croyais bien envoyer la sortie de 'for pkg...' sur l'entrée
standard de 'aptitude reinstall'.
Mais où l'envoyé-je en fait ?


Tu l'as bien envoyée sur l'entrée standard.

Qu'elle était mon erreur exactement ?


un petit exemple avec la commande cat :

% echo 'contenu' > fichier
% echo fichier | cat # entrée standard de cat
fichier
% cat fichier # argument de cat
contenu

--
Benoit Izac



Avatar
Hugolino
Le Fri, 31 Aug 2007 06:47:05 +0200, Benoit Izac a écrit:
Bonjour,

le 31/08/2007 à 01:42, Hugolino a écrit dans le
message :

Tu ne passes pas les noms des paquets en arguments de aptitude
reinstall mais sur l'entrée standard.


<soupir>C'est ça que je comprendrais jamais</soupir>

Je croyais bien envoyer la sortie de 'for pkg...' sur l'entrée
standard de 'aptitude reinstall'.
Mais où l'envoyé-je en fait ?


Tu l'as bien envoyée sur l'entrée standard.


OK, je vois : encore un problème de vocabulaire. (Et tant que je
n'aurais pas réussi à intégrer correctement ce vocabulaire, je
n'ariverais pas intégrer les notions essentielles qui sont derrière)

La notion d'entrée standard était un peu floue pour moi, je ne
comprenais pas que tu ne précises pas l'entrée standard de quoi.

Est ce que j'ai raison de croire ma commande échouait car aptitude n'est
pas prévu pour lire l'entrée standard ?

Ou est-ce que je dis une énormité car tous les programmes ont une entrée
standard.

Qu'elle était mon erreur exactement ?


un petit exemple avec la commande cat :

% echo 'contenu' > fichier
% echo fichier | cat # entrée standard de cat
fichier
% cat fichier # argument de cat
contenu


OK, merci.

Et la différence entre l'entrée standard et l'argument ?


--
Les hommes ont peut-être découvert le feu mais les femmes ont appris à
jouer avec...
Hugo (né il y a 1 368 025 999 secondes)



Avatar
Olivier Miakinen

Et la différence entre l'entrée standard et l'argument ?


Script nommé hugolino.sh :
------------------------------------
echo "Arguments :" $*

while read x
do
echo "Entrée standard :" $x
done
------------------------------------

$ hugolino.sh arg1 arg2 arg3
Arguments : arg1 arg2 arg3
machin truc
Entrée standard : machin truc
chose bidule
Entrée standard : chose bidule
^D
$

Avatar
Benoit Izac
Bonjour,

le 31/08/2007 à 18:24, Hugolino a écrit dans le
message :

Est ce que j'ai raison de croire ma commande échouait car aptitude n'est
pas prévu pour lire l'entrée standard ?


Je pense que oui (je ne connais pas aptitude).

Ou est-ce que je dis une énormité car tous les programmes ont une entrée
standard.


Oui, ls et date par exemple n'utilise pas l'entrée standard.

Qu'elle était mon erreur exactement ?


un petit exemple avec la commande cat :

% echo 'contenu' > fichier
% echo fichier | cat # entrée standard de cat
fichier
% cat fichier # argument de cat
contenu


OK, merci.

Et la différence entre l'entrée standard et l'argument ?


Si tu fais un peu de C, les arguments sont dans argv[], l'entrée
standard est ce que tu lis sur stdin. Si tu ne programmes pas, c'est
effectivement beaucoup plus difficile à expliquer et à comprendre.

Pour t'aider à comprendre, tu peux t'amuser avec le programme suivant :

#/bin/sh
cat > prog.c << EOF
#include <stdio.h>

int main(int argc, char *argv[])
{
int i;

printf("Le nom du programme est : %sn", argv[0]);
switch (argc) {
case 0 :
break;
case 1 :
printf("Il n'y a pas d'argumentn");
break;
case 2 :
printf("Son argument est [%s]n", argv[1]);
break;
default :
printf("Ses arguments sont :n");
for (i = 1; i < argc; i++)
printf(" %3d : [%s]n", i, argv[i]);
}

printf("Sur l'entree standard on a :n");
while ((i = getchar()) != EOF)
putchar(i);
return 0;
}
EOF
cc -o prog prog.c
echo blabla | ./prog abc de "fg h"
./prog < prog.c
./prog a # ^D pour finir la saisie

--
Benoit Izac



Avatar
Hugolino
Le Fri, 31 Aug 2007 20:44:13 +0200, Olivier Miakinen a écrit:

Et la différence entre l'entrée standard et l'argument ?


Script nommé hugolino.sh :


C'est sous quelle licence ? :)

------------------------------------
echo "Arguments :" $*

while read x
do
echo "Entrée standard :" $x
done
------------------------------------


OK,

Est qu'une définition de "argument" et "entrée standard" comme suit est
correcte:

Un argument est ce qui désigne les données que l'utilisateur peut
fournir au programme.
Si on est en CLI ce peut être un mot qu'on ajoute quand on appelle le
programme (dont le nom est un d'ailleurs un argument du shell).
Une option est un argument.
Un paramètre est un argument.

L'entrée standard (stdin) désigne *toutes* les données que le programme
lit en entrée. Exemple, la date du système, la température du proc ou
whatever.

Le truc, c'est qu'avec ces définitions les arguments font partie de
l'entrée standard. Mais ça ne me gêne pas.


Encore une question:

Dans mon post initial, je disais que j'avais fait:
8<-----------8<---------8<----------8<----------8<----------8<----------8<
09:49:21 /root # ls -l pkg-k6
16 -rw-r--r-- 2 root root 12762 ven 31/08/2007 03:57:52 pkg-k6
09:49:26 /root # for pkg in $(awk '/base/ {print $1}'
pkg-k6); do echo -n " "$pkg;done | aptitude reinstall -
Lecture des listes de paquets... Fait
Construction de l'arbre des dépendances... Fait
Lecture de l'information d'état étendu
Initialisation de l'état des paquets... Fait
Lecture des descriptions de tâches... Fait
Construction de la base de données des étiquettes... Fait
E: Badly formed pattern
Aucun paquet ne va être installé, mis à jour ou enlevé.
8<-----------8<---------8<----------8<----------8<----------8<----------8<

NB: aptitude ne semble pas avoir compris l'argument "resinstall", car il
ne le mentionne pas dans sa sortie.

Est ce que j'ai raison de penser que cette ligne de commande (argument
de GNU bash) s'exécute comme suit:
1) bash la lit et lance aptitude avec l'argument reinstall
2) le "-" signifie à bash qu'il devra envoyé la sortie de "for pkg ..."
à aptitude.
3) la sortie de ce qu'il y avait le pipe est correcte puisque si je la
copie pour la coller derrière "aptitude réinstall ", aptitud ce lance
correctement.
4) Donc c'est bash qui n'a pas le comportement attendu par moi car des
variables d'environnement (comme IFS par exemple) ne sont pas les même
dans le cas "1) + 2)" et le cas 3)

Est ce que mon interprétation de ce qui cause l'erreur "E: Badly formed
pattern" est correcte ?



Merci à toi et à Benoit.


--
echo "what is the universe"|tr "a-z " 0-7-0-729|sed 's/9.//g;s/-/+/'|bc
Hugo (né il y a 1 368 052 568 secondes)


Avatar
Stephane Dupille
Est qu'une définition de "argument" et "entrée standard" comme suit est
correcte:


<snip>

Un argument est ce qui désigne les données que l'utilisateur peut
fournir au programme.


En quelque sorte, oui. Les arguments sont des « mots » qu'on donne à
un programme. C'est ce que tu tapes après le nom de la commande.

Si on est en CLI ce peut être un mot qu'on ajoute quand on appelle le
programme (dont le nom est un d'ailleurs un argument du shell).
Une option est un argument.
Un paramètre est un argument.


Là, non. On peut voir l'entrée standard comme un fichier virtuel.
Techniquement, c'est un flux, en fait. C'est un fichier qui est ouvert
par défaut à un programme, et qui sert à lui passer des données, ou
pas.

Un programme a toujours trois fichiers de ce type :
- l'entrée standard (stdin), ouvert en lecture seule ;
- la sortie standard (stdout), ouvert en écriture seule ;
- la sortie d'erreur standard (stderr), ouvert en écriture seule.

C'est utilisé comme suit : un programme n'affiche pas son résultat à
l'écran, mais toujours sur sa sortie standard qui peut être branchée
vers l'écran (techniquement, le terminal), ou pas. Il est possible de
rediriger le flux de la sortie standard avec l'entrée standard d'un
autre programme.

Par exemple : cat va écrire sur la sortie standard le contenu d'un
fichier.

$ cat fic
foo
bar
foobar
baz
$

Grep est une commande qui permet de filtrer ce qu'on lui donne sur
son entrée standard. Par exemple, on peut dire à grep de ne sortir que
ce qui contient « ba » :

$ cat fic | grep ba
bar
foobar
baz
$

Ici, greppe ne voit jamais le fichier fic, elle ne sait même pas
qu'il existe. La preuve, en utilisant l'option « -l » de grep, qui
permet de forcer l'affichage du nom du fichier, au lieu d'afficher le
résultat de la recherche :

$ cat fic | grep -l ba
(standard input)

Il est aussi possible de demander à grep de chercher dans un
fichier, en lui fournissant son nom :

$ grep -l ba fic
grep -l ba fic
fic

La différence, c'est qu'ici on a fournit à grep un « mot », juste
une chaine de caractères. Grep a été programmé pour prendre ça comme
un nom de fichier, donc il va ouvrir le fichier, et chercher dedans.
Ici, grep manipule le fichier.

Alors que quand on lui envoie fic par l'entrée standard, c'est
directement le contenu qu'on lui envoie. Pas le contenu lui même.
Par exemple, nous pouvons chainer les grep :

$ cat fic | grep b
bar
foobar
baz
$ cat fic | grep f
foo
foobar
$ cat fic | grep b | grep f
foobar

Pourquoi ce résultat ? Parce que le deuxième grep dans la dernière
commande reçoit sur son entrée standard le résultat du premier grep.
L'entrée standard du second grep est la sortie standard du premier.
Donc « grep f » reçoit très exactement sur son entrée ce que « cat fic
| grep b » a affiché avant.


Sinon, pour la température du système, ce n'est pas lu sur l'entrée
standard (le premier grep au dessus n'envoie pas la température au
second), mais effectuée par une autre méthode : un appel système. En
gros, le programme va cogner à la porte du système et hurler « file
moi la température ! », le système, couard comme pas deux, va lui
filer en tremblotant.

Avatar
Benoit Izac
Bonjour,

le 01/09/2007 à 10:51, Stephane Dupille a écrit dans le message
:

$ cat fic | grep ba
$ cat fic | grep -l ba
$ cat fic | grep b
$ cat fic | grep f
$ cat fic | grep b | grep f


WARNING UUOC DETECTED ! ;-)

--
Benoit Izac

Avatar
Thierry PINELLI
Hugolino wrote:

Script nommé hugolino.sh :


C'est sous quelle licence ? :)


<007 ON>

License to kill

<007 OFF>


1 2