Colonne sans derniers caractères avec awk et printf

0

La question

J'ai ce script:

#!/bin/bash

f_status () {
        systemctl list-units | grep $1 | awk '{ printf("SERVICE STATUS:  %-25s \t %s \t %s \t %s\n",$1,$2,$3,$4) }'
}

f_line() {
        echo "-------------------------------------------------------------------------------------------"
}

echo ""
f_line
f_status "cron"
f_status "ssh"
f_line

Ce script me donne ce résultat:

-------------------------------------------------------------------------------------------
SERVICE STATUS:  cron.service                    loaded          active          running
SERVICE STATUS:  ssh.service                     loaded          active          running
-------------------------------------------------------------------------------------------

et je recherche comment faire pour supprimer ".de service" de la 3d de la colonne.

J'ai essayé avec substr($i, 0, -8) et ${1:-8}

Quelqu'un aurait-il une idée de comment se débarrasser de 8 caractères à partir de la fin pour la faire ressembler à ceci:

-----------------------------------------------------------------------------------
SERVICE STATUS:  cron                    loaded          active          running
SERVICE STATUS:  ssh                     loaded          active          running
-----------------------------------------------------------------------------------
awk bash printf
2021-11-23 11:39:15
3

La meilleure réponse

0

Vous n'avez jamais besoin grep lorsque vous utilisez awk depuis grep 'foo' file | awk '{print 7}' peut être écrite de la juste awk '/foo/{print 7}' file.

Plutôt que de compter les caractères, il suffit de retirer tout en commençant par la dernière .:

systemctl list-units |
awk -v tgt="$1" '
    {
        svc = $1
        sub(/\.[^.]*$/,"",svc)
    }
    svc == tgt {
        printf "SERVICE STATUS:  %-25s \t %s \t %s \t %s\n",svc,$2,$3,$4
    }
'

J'ai également renforcé la comparaison afin d'éviter les mauvais résultats si elle est appelée avec un nom de service qui est un sous-ensemble d'un autre service de nom ou contient des regexp metachars comme ..

2021-11-23 12:10:21

Merci pour les méga rapide réponse. Merci aussi pour les conseils sur le "grep" et "awk" - je vais garder cela à l'esprit. J'ai passé 4 heures à cette tâche et je n'avais aucune idée de comment le résoudre.
gacek

J'ai choisi Votre solution et suivi vos recommandations pour après le comportement de réponse. Encore merci et meilleures salutations!
gacek
0

Vous avez besoin de calculer la position de fin de course basé sur la longueur de la chaîne, envisager la suite de simple exemple, supposons file.txt le contenu

cron.service
ssh.service

alors

awk '{print substr($1,1,length($1)-8)}' file.txt

sortie

cron
ssh

Explication: les arguments pour substr sont de la chaîne, la position de départ, la position de fin, length retourne le nombre de caractères dans la chaîne.

(testé dans gawk 4.2.1)

2021-11-23 12:04:06

Merci pour l'explication. J'ai essayé de cette façon avant: substr($1, la longueur, -8), mais je ne pense pas que je devrais spécifier une variable qui doit compter le nombre de caractères.
gacek

@gacek length lorsque utilisé sans () est juste de la variable contenant le nombre de caractères dans l'ensemble de la ligne ($0) plutôt que de domaine particulier, par exemple si vous avez des fichiers avec de simples lignes: 123 456 alors {print length} donne 7comme il a 6 chiffres et de l'espace.
Daweo

concernant length when used without () is just variable - non, c'est encore un appel de fonction, c'est juste un raccourci pour length($0). Si c'était une variable puis, entre autres choses, vous pouvez assigner une valeur à elle, mais vous ne pouvez pas.
Ed Morton
0

vous pouvez utiliser gsub funtion dans awk,comme suit:

 systemctl list-units | grep 'cron' | awk '{gsub(".service","",$1); printf("SERVICE STATUS:  %-25s \t %s \t %s \t %s\n",$1, $2 ,$3,$4) }'
SERVICE STATUS:  crond                       loaded      active      running
2021-11-23 12:04:26

1) gsub() est pour faire de multiples substitutions alors que vous ne voulez faire de 1, de sorte que vous devriez être en utilisant sub() au lieu de cela, 2) le premier argument en faveur de l'un quelconque des *sub() des fonctions est une regexp, pas une chaîne, de sorte que vous devriez être à l'aide de regexp /.../, pas de chaîne "...", les délimiteurs, 3) vous devez ancrer votre regexp avec une terminaison de $ si vous supprimez la dernière occurrence sur la ligne, pas la première, 4) dont vous avez besoin pour échapper à la . dans une regexp ou il va correspondre à n'importe quel caractère, et pas seulement la . vous souhaitez faire correspondre, 5) vous n'avez pas besoin grep lorsque vous êtes à l'aide de awk depuis grep 'cron' | awk '{foo}' = awk '/cron/{foo}'.
Ed Morton

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................