[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Récupérer le résultat d'une commande sed dans une variable ou un fichier : problème...



Bonjour,

Je réagis rapidement :

Ma commande sed fait le boulot attendu en CLI si je prends un nom de fichier en argument, lequel fichier contient la chaîne multilignes à traiter.
Elle ne le fait pas quand je veux lire la chaîne multilignes qui est la MEME chaîne multilignes, qui est la valeur d'une variable précédemment définie (ici, TRUC).


Un nom de fichier est une chose : la commande va chercher ce que contient ce fichier.
Une variable en est une autre : la commande va lire la valeur de la variable.
... ou pas... J'ai un blanc... il doit manquer qqchose...
Faut-il effectuer une opération sur la variable TRUC qui contient la même chose que le fichier mon_fichier, pour pouvoir donner à sed l'argument qu'il attend (cad un nom de fichier) ?...


Rappel :
Le fichier contient une liste de lignes (dont certaines sont vides ou commencent par abc, sur lesquelles on ne fait aucun traitement ; mais c'est accessoire)
abc-----
foo
bar

abc-----
baz


Après le traitement, on veut :
abc-----
foo
  -> http://toto.com/foo
bar
  -> http://toto.com/bar

abc-----
baz
  -> http://toto.com/baz


CECI FONCTIONNE
$ sed '/^abc\|^$/! { p; s|^|  -> '"${DOMAIN}"'|g }'  mon_fichier
(affiche le résultat visé) 

$ RES=$(sed '/^abc\|^$/! { p; s|^|  -> '"${DOMAIN}"'|g }'  mon_fichier)
$ echo "$RES"
(affiche le résultat visé) 

CECI NE FONCTIONNE PAS 
A présent, mettons la chaîne multi-lignes à traiter dans une variable TRUC
$ TRUC=$(cat mon_fichier)
$ echo "$TRUC"
(affiche le texte à traiter) 

$ RES=$(sed '/^abc\|^$/! { p; s|^|  -> '"${DOMAIN}"'|g }'  "$TRUC")
sed: can't read 
(affiche le texte à traiter): No such file or directory:

***
Je me dis donc qu'il faut donner à sed l'argument qu'il attend, cad un nom de fichier, ce qui n'est pas le cas, car il cherche à ouvrir un fichier qui n'existe pas "No such file or directory".
***


Merci
Cordialement
RT
----- Mail original -----
De: "Marc Chantreux" <mc@unistra.fr>
À: "roger tarani" <roger.tarani@free.fr>
Cc: "Liste Debian" <debian-user-french@lists.debian.org>
Envoyé: Jeudi 4 Novembre 2021 16:54:56
Objet: Re: Récupérer le résultat d'une commande sed dans une variable ou un fichier : problème...

Bonjour,

> J'ai tenté diverses expressions, comme par exemple dans une variable :
> RES=$( sed '/^abc\|^$/! { p; s|^| -> '$DOMAIN'|g }')

* pas testé mais je doute que ton script passe avec autre chose que GNU sed.
* c'est très généralement une mauvaise idée de ne pas protéger le
  résultat d'une commande avec ""

donc j'aurais tendance à écrire

RES="$( sed "
    /./!d
    /^abc/d
    p
    s|^| -> $DOMAIN|g
")"

mais écrit comme ca, sed lit stdin alors que dans

> $(sed '/^abc\|^$/! { p; s|^| -> '"$DOMAIN"'|g }' "$RES" > mon_fichier)

ca lit dans un fichier qui s'appelle "$RES" et ca écrit dans mon_fichier

> En ligne de commande, j'obtiens exactement le résultat escompté sur stdout ou dans le fichier.

* tappe la commande
* si tout s'affiche bien, tappe

    RES="$(!!)"; echo "$RES"

normallement t'as la même chose. non ?

> J'obtiens le résultat aplati, sans séparateur : 
> foo bar baz truc machin 

c'est normal! il faut que tu comprennent la manière dont fonctionnne les
variable expansions. dans ton cas tu dois protéger l'expansion 2*:

* le moment ou il capture

RES="$( sed "
    /./!d
    /^abc/d
    p
    s|^| -> $DOMAIN|g
")"

et le moment ou tu affiches

echo "$RES" # qui ne fait pas du tout la meme chose que echo $RES

c'est parce que l'expansion de la variable se fait sur IFS:

    echo -n "$IFS"|xxd
    # les chaines des variables sont splitées avec " " "\t" et "\n"

si tu n'es pas sur: comme je le disais plus haut: mets des "" partout :)

> Quel mystère y a-t-il qui m'échapperait donc ?

si tu nous proposais un script avec une entrée et une sortie  du genre

<<. cat > from

abc def
abc def
abc def

ok 1
ok 2

.
<<. cat > expected
 -> perdu.comok 1
 -> perdu.comok 2
.
DOMAIN=perdu.com
RES="$( sed "
    /./!d
    /^abc/d
    s|^| -> $DOMAIN|g
" mon_sample )"
echo "$RES" > got
diff got expected

on pourrait probablement trouver le problème plus rapidement.

cordialement,

-- 
Marc Chantreux
Direction du numérique de l'Université de Strasbourg
Pôle de Calcul et Services Avancés à la Recherche (CESAR)
http://annuaire.unistra.fr/p/20200


Reply to: