web-dev-qa-db-ja.com

Perlスクリプトでawkコマンドを使用する

誰かがPerlスクリプトでコマンドのパイピングを使用する方法を提案できますか?特にawk?の呼び出しを伴うコマンド

df -Hを使用してディスク使用量を読み取り、%useを示す出力の最後から2番目の行を返すPerlスクリプトを作成しようとしています。端末にコマンドを直接入力すると、目的の出力が返されます。

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

このコマンドは正しい結果を返しています。ただし、逆ティックユーティリティで同じコマンドを使用すると、Perlスクリプトは多くのエラーをスローします。

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

同じコマンドがスクリプトで実行されないのはなぜですか?必要な結果を返す他の方法はありますか?

2
kiran bbnl

主な問題は、$がPerlにとって重要であることです。システムコマンドで使用する場合は、エスケープする必要があります。

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

そうでない場合、Perlは$(NF-3)をPerl変数として展開しようとします。変数$(Perlプロセスの実際のGID

$(

このプロセスの実際のgid。複数のグループのメンバーシップを同時にサポートするマシンを使用している場合、現在のグループのスペース区切りリストを提供します。

変数$)は、プロセスの有効なGIDです。

したがって、$(NF-3)list of groups you are a member of NF-3)と評価されます。たとえば、私のシステムでは:

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

次の問題は、awk呼び出しが間違っていることです。 %の使用は、$(NF-1)ではなく、$(NF-3)です。だから、あなたが欲しかったのは:

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

または、特定のしきい値(たとえば90)を超えるパーセンテージのみを印刷するには:

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

いずれにしても、Perl自体でdfの出力を処理することができます。

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

または

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

しきい値を設定するには:

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

または、より直接:

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

@array=($variable=~/foo/g)は、変数$variableの正規表現fooのすべての一致を配列@matchesに保存します。これは、dfawkで解析するのと同じ結果になります。

6
terdon