次のように、多くのパイプで動作する一連のコマンドがあります。
awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }' "/var/log/apache2/other_vhosts_access.log" | grep -v '127.0.0.1' | tr '[' '\0' | tr [:lower:] [:upper:] | sort -t' ' -s -k3
これはデフォルトでApacheログをフィルタリングし、3つの情報列を印刷します。最初の列はIPアドレス、2番目の列は時間、3番目の列は文字列です。出力はすべての列でソートできるため、「-m」を使用して時間フィールドをソートする必要があります。ソート順を逆にすることもできます。
ソートするパラメーターを保管し、結合されたストリングが実行されるようにするストリングが必要です。このような:
$AWK_CMD | $SORT_CMD $SORT_KEY $SORT_REV
どこ
SORT_CMD="sort -t' '"
SORT_KEY="-k$1" # $1 from cmd line arg
SORT_REV="$2" # Either -r or blank
このような文字列を作成できればOKです。問題は実行方法です。次のエラーが発生します。
awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }' "/var/log/apache2/other_vhosts_access.log" | grep -v '127.0.0.1' | tr '[' '\0' | tr [:lower:] [:upper:] | sort -t' ' -s -k3
Running ...
awk: '{
awk: ^ invalid char ''' in expression
ソートが正しくソートされない場合は無視してください。この問題は解決することができます。最終的なコマンド文字列を段階的に作成する方法を知りたいです。スクリプトでこのコマンドを実行する方法は次のとおりです。
$final_cmd
`$final_cmd`
編集:私が使ったスクリプト
KEY=$1 # Values {1, 2, 3}
REVERSE=$2 # Values {0, 1}
SORT_CMD="sort -t' ' -s"
SORT_KEY="-k$KEY"
if [[ $KEY -eq 2 ]]
then
SORT_KEY="-m -k2"
fi
if [[ $REVERSE -eq 1 ]]
then
SORT_REV="-r"
else
SORT_REV=
fi
final_cmd="awk '{ if (\$8 ~ \"isad\") {print \$2, \$5, \"SE\"} else {print \$2, \$5, \"ANT\"} }' $LOG_FILE '|' grep -v '127.0.0.1' '|' tr '[' '\0' '|' tr [:lower:] [:upper:] '|' $SORT_CMD $SORT_KEY $SORT_REV"
echo $final_cmd
echo "Running ..."
$final_cmd
ベストアンサー1
さまざまな部分をシェル関数に入れることができます。
awkfilter() {
awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }'
}
toupper() {
tr '[:lower:]' '[:upper:]'
}
dosort() {
sort -t' ' -s -k3
}
awkfilter < /var/log/apache2/other_vhosts_access.log |
grep -vF 127.0.0.1 |
tr '[' '\0' |
toupper |
dosort
これにより、選択肢を簡単に作成できます。
dosort() {
rev=
if [ "$2" = "reverse" ]
then
rev=-r
fi
sort -t' ' -s -k"$1" ${rev+"$rev"}
}
コマンドラインが長くなりすぎると、スクリプトで記述し、関数を使用してさまざまな部分に分割することが非常に役立つことがよくあります。