1
votes

Imprimer la sortie de deux commandes sur une seule ligne

Je fais ce travail:

1601.058
3.4811%
1452.514
3.48059%
1993.800
3.48006%
2085.585
3.47955%
2757.776
3.47902%
1370.237
3.47851%
1497.903
3.47798%

Et cela me donne la sortie suivante:

while sleep 5s
 do
  lscpu | grep 'CPU MHz:' | cut -d ':' -f 2 | awk '{$1=$1};1' && grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}'
done

Mais j'aimerais vraiment pour obtenir les deux valeurs sur une seule ligne. Chaque fois que j'essaie de faire cela, je rencontre un problème de variable de guillemet double / simple. Certes, j'ai retiré certains de ces trucs bizarres en ligne, donc je ne suis pas vraiment au courant à ce sujet. Je veux juste imprimer par ligne, horloge CPU et charger toutes les 5 secondes.

Pouvez-vous m'aider à trouver une meilleure façon de faire cela?


1 commentaires

Pensez à modifier pour afficher quelque chose que vous essayez qui ne fonctionne pas.


5 Réponses :


3
votes

Vous pouvez utiliser la substitution de processus pour exécuter lscpu et cat / proc / stat et alimenter une seule commande. Pas besoin d'utiliser des tuyaux.

awk '{printf "%s ", $1=NF}END{print ""}' <(date) <(date)
2019 2019

S'il n'y a qu'une seule commande d'entrée:

awk '{print $NF}' <(date)
2019

OU

date| awk '{print $1}'
Wed

Si plus d'une commande: Exemple, obtenez l'année de la commande à deux dates sur la même ligne. (exemple pas très utile, uniquement pour une démonstration)

while sleep 5; do
    awk '/CPU MHz:/{printf "%s ", $NF} /cpu /{print ($2+$4)*100/($2+$4+$5)"%"}' <(lscpu) /proc/stat
 done


1 commentaires

Bonne réponse. Un petit problème: <(cat / proc / stat) pourrait simplement être / proc / stat ; aucune raison pour un processus séparé et un FIFO pour le connecter.



0
votes

En écrivant ceci pour la lisibilité plutôt que pour l'efficacité, vous pourriez envisager quelque chose comme:

while sleep 5; do
  cpu_pct=$(lscpu | awk -F': +' '/CPU MHz:/ { print $2 }')
  usage=$(awk '/cpu / {usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}' /proc/stat)
  printf '%s\n' "$cpu_pct $usage"
done

Les substitutions de commandes coupent implicitement les nouvelles lignes à la fin, donc si lscpu | awk a une sortie qui se termine par une nouvelle ligne, var = $ (lscpu | awk) la supprime; par la suite, vous pouvez utiliser "$ var" sans que cette nouvelle ligne n'apparaisse.


1 commentaires

Merci pour la réponse super rapide, ainsi que la suggestion de publier mon échec.



1
votes

canaliser la sortie des 2 commandes dans coller

while sleep 5; do
    lscpu | awk -F':[[:blank:]]+' '$1 == "CPU MHz" {print $2}'
    awk '$1 == "cpu" {printf "%.4f%%\n", ($2+$4)*100/($2+$4+$5)}' /proc/stat
done | paste - -

Les 2 colonnes seront séparées par une tabulation.


1 commentaires

Vous pourriez simplement avoir un coller réutilisé plutôt que de redémarrer un nouveau par itération de boucle, non? C'est-à-dire: pendant le sommeil 5; fais ...; fait | coller - -



0
votes

Tout ce que vous avez à faire est de changer la nouvelle ligne de la première ligne en un séparateur différent. Quelque chose comme:

lscpu | ... | tr \\n : && grep ...


0 commentaires

0
votes

Vous pouvez également utiliser echo -n $ (command_with_stdout) . Le commutateur -n spécifie que la nouvelle ligne ( \ n ) sera omise.

while sleep 5s; do echo "$( lscpu | grep 'CPU MHz:' | cut -d ':' -f 2 | awk '{$1=$1};1' ) **** $( grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}' )"; done

Ou la même représentation sur une ligne:

while sleep 5s; do echo -n $( lscpu | grep 'CPU MHz:' | cut -d ':' -f 2 | awk '{$1=$1};1' ); echo -n ' **** '; echo $( grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}' ); done

EDIT: (supprimer le commutateur -n de echo selon le commentaire de Charles Duffy)

while sleep 5s; do
  echo -n $( lscpu | grep 'CPU MHz:' | cut -d ':' -f 2 | awk '{$1=$1};1' )
  echo -n ' **** '
  echo $( grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}' )
done


7 commentaires

echo -n n'est pas fiable - la spécification POSIX pour echo , lui permet de faire littéralement n'importe quoi lorsqu'on lui donne cet argument, y compris l'impression de -n en sortie; et certaines configurations d'exécution de bash font exactement cela. Il est beaucoup plus sûr d'utiliser printf '% s' "..." au lieu de echo -n "..." .


(Si vous examinez le lien ci-dessus, assurez-vous de consulter les sections UTILISATION DE L'APPLICATION et JUSTIFICATION)


... aussi, il doit être echo -n "$ (command_with_stdout)" avec les guillemets si vous ne voulez pas de * à remplacer par des noms de fichiers, un onglet à remplacer par un espace, etc. discussion pertinente dans BashPitfalls # 14 .


(En ce qui concerne l'assertion "certaines configurations d'exécution", essayez d'exécuter set -o posix; shopt -s xpg_echo; echo -n foo - gardez à l'esprit que ces indicateurs peuvent également être définis via des variables d'environnement ou au moment de la compilation pour le shell lui-même, donc le code ci-dessus n'est pas le seul moyen d'entrer dans cet état; et certains autres shells se comportent de cette manière dès la sortie de la boîte).


Les citations sont un peu plus compliquées et pas claires. Il existe de nombreux "Shells" dans différents systèmes Linux. Si j'utilise des guillemets, je ne peux pas utiliser d'autres fonctionnalités ou je dois les utiliser autrement que celles auxquelles je suis habitué. La même chose s'applique aux crochets. POSIX est également très ridicule. La plupart des créateurs de shell ignorent le POSIX. Même entre les deux populaires "Sh" et "Bash" il y a de grandes différences. En raison de différences "Sh" vs. "Bash" a cessé de travailler sur l'un des projets de l'entreprise pendant toute la semaine :-). Certains ignorants ont introduit dans notre système le script Sh, pas le script Bash utilisé dans notre entreprise.


Si votre code "fonctionne" uniquement sans guillemets, ce code présente de sérieux bogues (certains sont décrits dans le lien BashPitfalls ci-dessus, d'autres sont traités dans BashFAQ # 50 ). bash est un shell de la famille POSIX; contrairement à zsh, il suit les règles POSIX, et les directives de citation POSIX s'appliquent dans leur intégralité lors de l'écriture de code pour bash.


POSIX est vraiment drôle. Je suis assis derrière le système Linux il y a 20 ans. Shell a présenté quelque chose de différent qu'aujourd'hui :). Aujourd'hui, POSIX n'est qu'un gros gâchis. Chacun développe son propre Shell dans lequel rien ne fonctionne sous POSIX. Si le script fonctionne bien sur un système particulier, sur un noyau particulier, dans un shell particulier, il n'y a aucune raison de s'en inquiéter. C'est juste un script et non une application. Le script Shell est juste mon petit passe-temps :). Veuillez ne pas demander de normes et de normalisation. C'est fatiguant. Quoi qu'il en soit, merci pour ta direction et ton avertissement. Je vous en suis reconnaissant.