パラメータを渡そうとするシェルスクリプトがあり、スクリプトに空の出力が表示されますdate
。ARGV[1]
これはコマンドです:
#!/bin/bash
dt=$(date -d "yesterday" '+%m%d%Y')
cat /tmp/log.$AUTOSERVE.$dt \
| perl -ne '/STATUS:\s+(\w+).+MACHINE:\s+(\w+.\w+.\w+)$/ && print join( "\t", $1, $2 ). "\n"' \
| grep -E '(SUCCESS|FAILURE|TERMINATED)' \
| cut -f2 \
| sort \
| uniq -c \
| perl -ne '/^\s+(\d+)\s+(.*)$/ && print join("\t", '$ARGV[1]', $ENV{AUTOSERV}, $2, $1) . "\n"' $date_YYYYMMDD \
> /tmp/output.txt
私は何が間違っていましたか?
ここで私がやりたいことを説明します。
毎日次の名前でログファイルを生成します。
log.$AUTOSERVE.mmddyyyy
ログファイルには次のデータが含まれます。
理解を深めるために、入力日を変更しました。
Time Message
____________________________________________
[11/16/2023 07:13:45] CAUAJM_I_12345 The application has rollover
[11/16/2023 07:13:45] CAUAJM_I_11111 The machine 111.test.com has lost connection
[11/16/2023 07:13:45] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: FAILURE JOB: ABC MACHINE: 111.test.com EXITCODE: 1
[11/16/2023 07:13:45] CAUAJM_I_40245 [222.test.com connected to ABC]
[11/16/2023 07:13:45] CAUAJM_I_40245 EVENT: CHANGE_STATUS ALARM: JOBFAILURE JOB: ABC EXITCODE: 1
[11/16/2023 07:13:45] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: TERMINATED JOB: XYZ MACHINE: 222.test.com
[11/16/2023 07:13:46] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: STARTING JOB: 123 MACHINE: 333.test.com
[11/16/2023 07:13:46] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: SUCCESS JOB: 456 MACHINE: 444.test.com EXITCODE: 0
[11/16/2023 07:13:46] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: SUCCESS JOB: ABC123 MACHINE: 555.test.com
[11/16/2023 07:13:45] CAUAJM_I_40245 [222.test.com connected to ABC]
[11/16/2023 07:13:45] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: FAILURE JOB: ABC MACHINE: 111.test.com EXITCODE: 1
[11/16/2023 07:13:45] CAUAJM_I_40245 [333.test.com connected to 123]
[11/16/2023 07:13:45] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: TERMINATED JOB: XYZ MACHINE: 222.test.com
[11/16/2023 07:13:46] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: STARTING JOB: 123 MACHINE: 333.test.com
[11/16/2023 07:13:46] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: SUCCESS JOB: 456 MACHINE: 444.test.com
[11/16/2023 07:13:46] CAUAJM_I_40245 EVENT: CHANGE_STATUS STATUS: SUCCESS JOB: ABC123 MACHINE: 555.test.com EXITCODE: 0
このシェルスクリプトは、log
このファイルのMACHINEおよびSTATUS検索文字列をフィルタリングし、各システムで実行されているジョブの数を計算します。
私が得た結果は次のとおりです。
NP2 111.test.com 2
NP2 222.test.com 2
NP2 444.test.com 2
NP2 555.test.com 2
$date_YYYYMMDD
に変えようとしました。$dt:
cat /tmp/log.$AUTOSERVE.dt \
| perl -ne '/STATUS:\s+(\w+).+MACHINE:\s+(\w+.\w+.\w+)$/ && print join( "\t", $1, $2 ). "\n"' \
| grep -E '(SUCCESS|FAILURE|TERMINATED)' \
| cut -f2 \
| sort \
| uniq -c \
| perl -ne '/^\s+(\d+)\s+(.*)$/ && print join("\t", $ARGV[1], $ENV{AUTOSERV}, $2, $1) . "\n"' $dt \
> /tmp/output.txt
ただし、次のエラーが発生します。
Can't open 11152023: No such file or directory.
$AUTOSERVE
この出力に値を提供する環境変数があると仮定すると、NP2
予想される結果は次のとおりです。
11152023 NP2 111.test.com 2
11152023 NP2 222.test.com 2
11152023 NP2 444.test.com 2
11152023 NP2 555.test.com 2
ベストアンサー1
似たようなものが欲しいようです。
#! /bin/sh -
DT=$(date -d yesterday +%m%d%Y) || exit
export DT
exec perl -lne '
if (
($status, $machine) = /STATUS:\s+(\w+).+MACHINE:\s+(\w+\.\w+\.\w+)$/ and
$status =~ /^(SUCCESS|FAILURE|TERMINATED)\z/
) {$count{$machine}++}
END {
for (keys %count) {
print join "\t", $ENV{DT}, $ENV{AUTOSERVE}, $_, $count{$_};
}
}' < ~/tmp/log."$AUTOSERVE.$dt" > ~/tmp/output.txt
メモ:
たとえば、固定名のファイルは誰でも書き込み可能なディレクトリで使用しないでください。
/tmp
したがって、ここに切り替えるか、または//...の専用領域を使用してください~/tmp
。/var
~/var
~/.local
$XDG_RUNTIME_DIR
このコードにはbashに関連する内容がないため、bashの依存関係を追加する必要はありません。
追加の
-n
パラメータはperl
スクリプトへの入力です。Chrisがすでに述べたように、あなたの引用に問題があります。
あなたは
AUTOSERV
/AUTOSERVE
違いがあります。.
単一文字に一致する正規表現演算子です。テキストポイントを一致させるには、\.
またはを使用します。[.]
使用法は
date
GNUによって異なります。すべてのdate
実装が-d
オプションをサポートしているわけではなく、サポートしている場合は、BSDの項目や認識できない項目(ビジボックスやおもちゃ箱yesterday
など)など、まったく関連のない項目に使用できます。このスクリプトをGNU以外のシステムに移植する必要がある場合は、日付操作も可能です。date
perl
次のように、単一の正規表現を使用するように簡単に変更できます。
/STATUS:\s+(?:SUCCESS|FAILURE|TERMINATED)\b.+MACHINE:\s+(\w+.\w+.\w+)$/
マシンのリストをアルファベット順に並べ替えるには、を
keys %count
に置き換えます。sort cmp, keys %count
exec
このようなラッパースクリプトで非常に一般的なのは、プロセスを保存することです。perl
子プロセスで実行し、待つのではなく、同じプロセスで実行するようにシェルに指示します。cmd
+fork()
&をexec(cmd)
実行しますがwait(child)
(exec cmd
おそらくと呼ばれる必要がありますnofork cmd
)exec(cmd)
、入力に時間がかかりますが、システムの実行はより簡単で短く、リソースの使用量が少なくなります。%m%d%Y
タイムスタンプ形式を選択することはお勧めできません。あいまいで、語彙順(の出力と同様ls
)が年代順と一致しません。%Y-%m-%d
それとも%F
普遍的に認識され、語彙的に年代順(少なくとも0001から9999まで)にソートされるので、より良いです。cat
ファイルをリンクするコマンドです。ファイルに使用することは意味がありません。cmd < input > output
(または、<input cmd >output
しかしいいえcmd > output < input
input
)には、読み取り用に開くことができない場合はcmd
実行されず、output
削除されないという追加の利点があります。
1たとえば、ここに-MPOSIX
aBEGIN{@t = localtime; $t[3]--; $dt = strftime "%m%d%Y", @t}
またはハッキングとして追加します-M'POSIX;@t = localtime; $t[3]--; $dt = strftime "%m%d%Y", @t'
。