Comment supprimer les deux dernières lignes d’une sortie en utilisant AWK?

J’essaie de faire une représentation graphique d’une sortie qui montre la mémoire libre du serveur du jour actuel (qui est affichée approximativement par heure), à ​​partir de cette sortie je ne veux pas les deux premières lignes et les deux dernières, les deux premières i peut facilement supprimer avec le NR, bien que j’ai eu des problèmes avec les deux derniers, la seule façon que j’ai trouvé était d’inverser la sortie entière supprimer les deux premières lignes et puis inverser à nouveau son état normal.

Une façon meilleure / correcte de supprimer les deux dernières lignes mais faites-le dans AWK?

c’est ce que j’ai jusqu’ici et fonctionne bien.

echo 'graphics (freemem)' echo 'GiB 0 500k 1M 1,5M' sar -r | tail -r | awk 'NR > 2{ print }' | tail -r | nawk ' NR > 4{ LINE = sprintf("%" int(($2 / 100000)*2 )"s", " "); gsub(/ /, "#", LINE); print $1, LINE; } ' 

METTRE À JOUR

Donc, je l’ai fait d’une autre manière parce que cela faciliterait la lecture du script et cela fonctionne pour moi, mais pour tout autre gars qui doit faire cela, utilisez soit la manière précédente, soit la façon dont les gars ont répondu.

 echo 'graphics (freemem)' echo 'GiB 0 500k 1M 1,5M' sar -r | nawk ' NR > 4 && $1 !~ /Average/ && $1 !~ /^$/ { LINE = sprintf("%" int(($2 * 2) / 100000 )"s", " "); gsub(/ /, "#", LINE); print $1, LINE; } ' 

MISE À JOUR 2

Donc, ce que je veux faire, c’est une représentation graphique des données surveillées, cette sortie est mise à jour toutes les heures, gardez à l’esprit que la longueur des lignes varie selon les heures. Donc, c’est la sortie réelle de sar -r que je reçois.

 . SunOS doc 5.10 00:00:00 freemem freeswap 01:00:01 1624430 19474799 02:00:00 1624421 19474738 03:00:00 1624413 19474683 04:00:00 1624527 19475309 05:00:00 1624525 19475290 06:00:00 1624517 19475232 07:00:01 1624510 19475176 08:00:00 1624503 19475120 08:20:00 1539793 18771472 08:40:00 1509924 18535201 09:00:00 1500681 18492050 09:20:00 1494254 18435535 09:40:00 1479623 18266664 10:00:00 1486372 18317241 10:20:00 1480565 18269032 10:40:00 1479030 18260247 11:00:01 1476462 18237731 11:20:00 1475999 18234221 11:40:00 1478854 18259827 12:00:00 1478223 18254861 12:20:00 1482956 18294572 12:40:00 1479061 18260565 13:00:00 1470463 18185441 13:20:00 1474090 18217961 13:40:00 1478585 18257393 14:00:00 1478219 18255445 14:20:00 1474327 18223749 14:40:00 1470468 18190676 15:00:00 1471941 18204282 15:20:00 1474138 18223380 15:40:00 1471698 18202561 16:00:00 1470316 18191099 16:20:00 1467203 18163653 16:40:00 1468943 18179148 Average 1549994 18855701 

Donc, nous ne nous soucions pas de freeswap et nous ne l’utilisons pas. Nous nous soucions uniquement des résultats de freemem. Donc, ce que j’essaie de faire, c’est de prendre en entrée cette colonne et de “traduire” le nombre en “#” par un calcul afin que je puisse ensuite spécifier la quantité de données dans la représentation graphique. Cependant, il y a des lignes au début et à la fin de la sortie dont je n’ai pas besoin, donc j’ai besoin de les supprimer.

C’est le code de travail que j’ai maintenant

 echo '\ngraphics (freemem)' echo 'GiB 0 500k 1M 1,5M' sar -r | awk 'NR > 2 {print P2} {P2=P; P=$0}' | nawk ' NR > 4 { LINE = sprintf("%" int(($2 * 2) / 100000 )"s", " "); gsub(/ /, "#", LINE); print $1, LINE; } ' 

la sortie correcte est donc celle-ci:

 graphics (freemem) GiB 0 500k 1M 1,5M 01:00:01 ################################ 02:00:00 ################################ 03:00:00 ################################ 04:00:00 ################################ 05:00:00 ################################ 06:00:00 ################################ 07:00:01 ################################ 08:00:00 ################################ 08:20:00 ############################## 08:40:00 ############################## 09:00:00 ############################## 09:20:00 ############################# 09:40:00 ############################# 10:00:00 ############################# 10:20:00 ############################# 10:40:00 ############################# 11:00:01 ############################# 11:20:00 ############################# 11:40:00 ############################# 12:00:00 ############################# 12:20:00 ############################# 12:40:00 ############################# 13:00:00 ############################# 13:20:00 ############################# 13:40:00 ############################# 14:00:00 ############################# 14:20:00 ############################# 14:40:00 ############################# 15:00:00 ############################# 15:20:00 ############################# 15:40:00 ############################# 16:00:00 ############################# 16:20:00 ############################# 

Vous pouvez stocker la ligne, faire des choses et imprimer après un certain temps pour que vous puissiez savoir si vous êtes dans la dernière ligne ou non. Mais c’est trop jouer au golf quand on a des outils comme la head et la tail .

Il suffit de head la sortie vers la head avant de la passer à awk :

 head -n -2 

Tester

 $ seq 10 1 2 3 4 5 6 7 8 9 10 $ seq 10 | head -n -2 1 2 3 4 5 6 7 8 

Comme vous n’avez pas de tête GNU vous permettant de faire cela, vous pouvez conserver les variables avec awk :

 awk '{if (prev_prev_line) print prev_prev_line; prev_prev_line=prev_line} {prev_line=$0}' 

Cela décale les lignes, de sorte que vous ayez dans prev_prev_line le contenu de la ligne que vous aviez il y a deux lignes:

 NR $0 prev_line prev_prev_line 1 1 - - 2 2 1 - 3 3 2 1 4 4 3 2 .... NR-1 NR-1 NR-2 NR-3 NR NR NR-1 NR-2 

Donc, puisque vous travaillez avec prev_prev_line , vous prev_prev_line par traiter du 1er au (NR-2) ème ligne.

Donc, dans prev_prev_line vous avez la ligne qui s’est produite il y a deux lignes. De cette façon, vous n’utilisez pas les deux dernières lignes dans la sortie.

Voyez comment cela fonctionne avec un exemple:

 $ awk '{if (prev_prev_line) print NR,prev_prev_line; prev_prev_line=prev_line} {prev_line=$0}' < <(seq 10) 3 1 4 2 5 3 6 4 7 5 8 6 9 7 10 8 

si rien ne fonctionne

 ... | sed '$d' | sed '$d' 
 $ seq 5 | awk 'NR>2{print p2} {p2=p; p=$0}' 1 2 3 

Compte tenu de votre question modifiée:

 $ cat tst.awk BEGIN { print "\ngraphics (freemem)" print "GiB 0 500k 1M 1,5M" } /^[0-9: ]+$/ { line = sprintf("%*s", int(($2*2)/100000), "") gsub(/ /,"#",line) print $1, line } 

.

 $ awk -f tst.awk file graphics (freemem) GiB 0 500k 1M 1,5M 01:00:01 ################################ 02:00:00 ################################ 03:00:00 ################################ 04:00:00 ################################ 05:00:00 ################################ 06:00:00 ################################ 07:00:01 ################################ 08:00:00 ################################ 08:20:00 ############################## 08:40:00 ############################## 09:00:00 ############################## 09:20:00 ############################# 09:40:00 ############################# 10:00:00 ############################# 10:20:00 ############################# 10:40:00 ############################# 11:00:01 ############################# 11:20:00 ############################# 11:40:00 ############################# 12:00:00 ############################# 12:20:00 ############################# 12:40:00 ############################# 13:00:00 ############################# 13:20:00 ############################# 13:40:00 ############################# 14:00:00 ############################# 14:20:00 ############################# 14:40:00 ############################# 15:00:00 ############################# 15:20:00 ############################# 15:40:00 ############################# 16:00:00 ############################# 16:20:00 ############################# 16:40:00 ############################# 

S’échapper de la table pour faire des calculs sur le fichier

 awk '{if (NR > 2 && NR < '$(( $(wc -l <$file) -1))')print $0}' $file 

Si le numéro d'enregistrement est supérieur à 2, nous avons sauté les 2 premières lignes. S'il est inférieur au total des lignes moins 1, nous nous sums arrêtés avant les deux derniers (vous pouvez utiliser -2 si vous utilisez <=).