web-dev-qa-db-fra.com

Utilisation de la commande awk dans le script Perl

Quelqu'un peut-il suggérer comment utiliser la tuyauterie de commandes dans un script Perl? Plus précisément, les commandes impliquant l’appel awk?

J'essaie de créer un script Perl qui lira l'utilisation du disque en utilisant df -H et renverra l'avant-dernière ligne de la sortie, qui indique le% d'utilisation. La saisie directe de la commande dans le terminal renvoie la sortie souhaitée.

df -H | awk '{print $(NF-3)}'

Cette commande renvoie les bons résultats. Mais lorsque vous utilisez la même commande dans l'utilitaire de tick inversé, le script Perl génère beaucoup d'erreurs.

$thirdlast=`df -H | awk '{print $(NF-3)}'`;
print $thirdlast;

Pourquoi la même commande ne s'exécute-t-elle pas dans le script? Existe-t-il un autre moyen de renvoyer les résultats requis?

2
kiran bbnl

Le problème principal est que le $ est important pour Perl. Lorsque vous l'utilisez dans une commande système, vous devez y échapper:

$thirdlast=`df -H | awk '{print \$(NF-3)}'`;
print $thirdlast;

Sinon, Perl essaiera de développer $(NF-3) en tant que variable Perl. La variable $(est le vrai GID du processus Perl :

$ (

Le vrai gid de ce processus. Si vous êtes sur un ordinateur prenant en charge l’appartenance simultanée à plusieurs groupes, donne une liste de groupes séparés par des espaces.

La variable $) est le GID effectif du processus:

Donc, $(NF-3) est évalué à list of groups you are a member of NF-3). Par exemple, sur mon système, c'est-à-dire:

$ Perl -le 'print "$(NF-3)"'
1001 27 29 111 112 1001NF-3)

Le problème suivant est que votre appel awk est incorrect. Le % utilisé est $(NF-1) et non $(NF-3). Alors, ce que tu voulais, c'est:

$thirdlast=`df -H | awk '{print \$(NF-1)}'`;

Ou, pour n’imprimer que des pourcentages supérieurs à un certain seuil, par exemple 90:

$thirdlast=`df -H | awk '(\$(NF-1)>90){print \$(NF-1)}'`;

Dans tous les cas, vous pouvez simplement traiter la sortie de df en Perl lui-même:

$thirdlast=`df -H`;
@matches=($thirdlast=~/(\S+%)/g);
print "@matches\n";

Ou

@matches=(`df -H`=~/(\S+%)/g);
print "@matches\n";

Et pour définir un seuil:

@matches=(`df -H`=~/(\S+%)/g);
@above90=grep {$_>90} @matches;
print "@above90\n";

Ou plus directement:

@matches=grep {$_ >90} (`df -H`=~/(\S+%)/g);
print "@matches\n";

La @array=($variable=~/foo/g) enregistre toutes les correspondances de l'expression régulière foo dans la variable $variable dans le tableau @matches. Cela aura le même résultat que d'analyser la df avec awk.

6
terdon