Ceci :
echo "" | tr '' '\ n' | sed "s |. * | $ RANDOM |"
Ou ceci:
echo "" | tr '' '\ n' | sed "s |. * | $ (echo $ RANDOM) |"
Affiche une liste de 5 nombres (l'espace est remplacé par une nouvelle ligne, sed remplace chaque ligne par $ RANDOM), et ces 5 nombres seront tous les mêmes :
$ echo " " | tr ' ' '\n' | sed "s|.*|$(echo $RANDOM)|" 21590 21590 21590 21590 21590
C'est parce que le remplacement de $ RANDOM par une valeur aléatoire ne se produit qu'une seule fois. p >
Quel est le moyen le plus simple et le plus court, de préférence en n'utilisant que sed, pour afficher un nombre aléatoire différent pour chaque ligne. c'est-à-dire pour fournir un "flux d'entrée secondaire" qui diffère pour chaque ligne gérée par sed?
Je pourrais le faire avec xargs, mais je me demande s'il existe un moyen de le faire uniquement avec sed. >
6 Réponses :
Si vous voulez le même nombre aléatoire
x=0 while (($x < 5)); do random=$(cat /dev/urandom | tr -cd '0-5' | head -c 8); echo "$random";((x++));done
Si vous voulez un nombre différent à chaque fois. Le problème ici est qu'il est plus difficile de définir le nombre de caractères que vous obtenez
random=$(cat /dev/urandom | tr -cd '0-5' | head -c 8) x=0 while (($x < 5)); do echo "$random";((x++));done
Ou plus logiquement pour le même nombre
echo -e "$RANDOM\n$RANDOM\n$RANDOM\n$RANDOM\n$RANDOM"
ou plus logiquement pour un numéro différent
random=$(cat /dev/urandom | tr -cd '0-9' | head -c 5) echo -e "$random\n$random\n$random\n$random\n$random"
Merci Goose. J'ai déjà ce type d'approches, je cherchais une solution sed, selon la question initiale. Normalement, je voterais contre cela, mais vous avez fait de gros efforts et vous êtes assez nouveau sur la plate-forme, donc je ne le ferai pas. N'oubliez pas de répondre à la question initiale lorsque vous répondez aux questions. Les informations environnantes sont également acceptables à mon humble avis, mais il devrait être clairement indiqué que vous saviez qu'elle diffère de la question originale à mon humble avis. Merci, et que Dieu vous bénisse.
Quel est le moyen le plus simple et le plus court, de préférence en n'utilisant que sed, pour imprimer un nombre aléatoire différent pour chaque ligne? p >
Réponse:
perl -e 'printf "%05s\n",int(rand(100000)) for (1..5)'
ou simplement:
echo " " | tr ' ' '\n' | perl -pe 's|.*|int(rand(89999))+10000|e'
Explication :
Je ne vois pas pourquoi on ne devrait pas utiliser Perl, ou tout autre outil peut-être plus adapté à ce travail. Dans l'OP, il n'y a aucune allusion à une raison de s'en tenir à sed
, ce qui n'est au contraire indiqué que comme une préférence.
Je me demande pourquoi on passerait par une substitution dans l'ordre pour imprimer cinq nombres aléatoires. Aucun détail n'est donné sur la situation dans son ensemble, mais cela me rend certainement curieux.
Merci pour l'alternative Perl, super idée!
Excellente réponse vraiment. Fonctionne toujours seq 5 | perl -pe 's |. * | int (rand (89999)) + 10000 | e'
Dépend de votre version de sed
, mais -
$: cat x a b c d e $: sed 's/.*/printf "%05d\n" $RANDOM/e' x 30181 30514 24742 28555 26267
Le e
signifie e
xecute , et génère un sous-shell, alors méfiez-vous du coût.
Vous pouvez formater la sortie. printf "% 07.7s \ n" $ (($ RANDOM% 10000)) $ (($ RANDOM% 10000))
imprimera toujours 7 chiffres avec un pavé zéro non significatif et améliorera les contraintes par rapport à la valeur par défaut gamme, ce qui fait 10000 nombres commençant par 1, 10000 nombres commençant par 2 et 2767 commençant par 3 sur un total de 32 767 mis à part de ceux de la plage normale 0-9999 - pas un distribution idéale. Vous pouvez également simplement utiliser awk
pour obtenir de meilleurs nombres aléatoires.
Réponse très cool, j'adore. Beau travail Paul. Je n'étais pas au courant de l'option e
execute / eval dans sed. Les sous-coquilles sont tout à fait acceptables.
Ou, avec seulement des changements minimes à ce que l'OP avait essayé: echo "" | tr '' '\ n' | sed 's |. * | echo $ RANDOM | e'
.
@simlev sympa! Merci pour toutes vos contributions sur la question aussi
Hmm, pour une raison quelconque, cela ne semble plus fonctionner. sed 4.7
dans Bash 5.0.17 (1)
Cela pourrait fonctionner pour vous (GNU sed et Bash):
shuf -i 1-100000 -n 5
Ceci remplace les nombres 1 à 5 par echo $ RANDOM
et évalue chaque ligne.
/ p>
NB GNU sed utilise / bin / sh
qui peut être dirigé via un lien symbolique vers / bin / dash
auquel cas la variable d'environnement $ RANDOM
sera pas être trouvé. Il existe différentes solutions pour contourner ce problème, mais la plus simple (bien que potentiellement dangereuse) est:
sudo ln -sf /bin/bash /bin/sh # run sed sudo ln -sf /bin/dash /bin/sh
Une autre alternative:
seq 5 | sed 's/.*/echo $RANDOM/e'
Très similaire à la réponse de Paul. Je ne connaissais pas l'option eval in-sed. Génial.
Hmm, pour une raison quelconque, cela ne semble plus fonctionner. sed 4.7
dans Bash 5.0.17 (1)
Non, il est impossible de faire cela avec sed uniquement car sed n'a pas la capacité de générer des nombres aléatoires. Ce n'est même pas sed qui le fait dans votre exemple posté, c'est le shell générant un nombre aléatoire avant que sed soit appelé. Tout ce que sed voit est "s |. * | 21590 |"
.
Si vous voulez faire cela en utilisant des outils standard dans n'importe quel shell sur n'importe quelle boîte UNIX, vous pouvez le faire avec n'importe quel awk:
$ seq 5 | awk -v seed="$RANDOM" 'BEGIN{srand(seed)} {print rand()}' 0.0873814 0.536876 0.535788 0.881146 0.354652
Voir https://www.gnu.org/software/gawk/manual/gawk.html#Numeric-Functions pour plus d'informations sur rand ()
et je peux fournir C&V si vous ' êtes intéressé par la recherche d'une solution awk.
Une façon de répondre à votre commentaire ci-dessous:
$ echo " " | tr ' ' '\n' | awk '{sub(/.*/,rand())}1' 0.924046 0.593909 0.306394 0.578941 0.740133
Oui, je sais que c'est la coquille dans mon exemple, d'où la question. Merci pour l'alternative awk, excellente idée.
Ce n'est malheureusement pas vraiment utilisable. Les nombres générés sont les mêmes à chaque fois (même entre votre sortie et la mienne c'est la même chose!), Et essayer de prérégler l'entropie conduit à ce que tous les nombres soient les mêmes lorsqu'un tube est utilisé, voir: seq 5 | awk '{srand (); print rand ()}'
Ce n'est pas ainsi que vous résoudriez ce problème car srand () se base sur l'heure actuelle par défaut et rand () utilise la valeur précédente comme une graine, donc vous le forcez à toujours afficher le même nombre pour chaque ligne. J'ai ajouté une approche à cela, mais cela fait 2 ans que vous avez posé cette question - posez une nouvelle question de suivi si vous souhaitez de l'aide.
J'ai trouvé une solution dans ce qui suit:
$ seq 5 | sed "s/.*/date +%N | grep -o '[0-9][0-9][0-9][0-9][0-9]$'/e" 16794 76358 17143 60690 70506
Il utilise les 5 derniers chiffres de la minuterie nanoseconde pour générer un nombre aléatoire de qualité d'entropie raisonnablement aléatoire.
Créer un sous-shell pour appeler date
une fois par ligne d'entrée serait extrêmement lent. Littéralement des milliers de fois plus lent que d'appeler rand ()
depuis awk comme dans ma réponse
Pourquoi avez-vous besoin d'utiliser
sed
? Tout ce dont vous avez besoin est une ligne aléatoire sur chaque ligne?Non, ce n'est qu'un exemple simplifié. Il y a d'autres façons de le faire, mais la question est de savoir si c'est possible dans sed.
Ne pensez pas que
sed
a une construction interne pour générer des nombres aléatoires.awk
aIl semble que votre question ait retenu l'attention et plusieurs réponses. Pourriez-vous s'il vous plaît fournir un suivi en partageant comment vous avez finalement résolu votre problème, laquelle des réponses que vous avez trouvée la plus utile, et éventuellement en ajoutant des détails sur le contexte dans lequel cet extrait est utilisé?
@simlev, merci de me le rappeler. J'ai donné des commentaires sur chacune des réponses. Paul Hodges se rapproche le plus de la solution "all-in-sed" (avec l'option eval / execute de sed utilisée pour créer un sous-shell), et il ajoute un joli printf "custom length" en même temps. potong a une deuxième place digne qui utilise une approche similaire.
@Roel Oui, c'est la réponse que j'ai également votée. J'utilise principalement Perl au lieu de
sed
, donc j'étais curieux de comprendre les raisons de cette exigence.