重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

Ubuntuサーバーで
次のように、webサーバーのログから、アクセス時間部分を取り出しまた。
grep -F " " /var/log/apache2/access.log | awk '{print $4}' | cut -b 14,15,17,18,20,21
さらに、ある時間以降のログを取り出すために
grep -F " " /var/log/apache2/access.log | awk '{print $4}' | cut -b 14,15,17,18,20,21 | awk '$1>"201030"'
で、20時10分30秒以降のアクセス時間を取り出すことができます。

しかし、比較すべき時間を変数にすると、正しく抽出されません。
変数をTMPTIMEとすると
awk '$1>$TMPTIME'
ではダメでした。
${TMPTIME}
としてもダメです。

""で囲まれていないのでダメなのかと思い、変数に""を連結して、"変数"としてもダメでした。
どこがいけないのでしょうか。
よろしくご教示ください。

A 回答 (1件)

シェルの変数展開の仕組と、awkの文法について、勉強しましょう。



その TMPTIME 変数は、シェルの変数ですか?awk内の変数ですか?その区別がついてない状態ですか?


コマンドを入力すると、$変数名 といった部分は、先に展開され、その結果がコマンドへ送られます。

DIRNAME='X'
ls $DIRNAME

みたいにした場合、
lsコマンドが $DIRNAME の内容を解釈するのではなく、シェルが先に
ls X
に置き換えています。 ls コマンドは、単に X という引数を受けるだけです。
もとが DIRNAMEという変数だったことはわかりません。

シングルクオートには、この変数展開をしない、という機能があります。


awk '$1>$TMPTIME'
というのは、シングルクオートにより変換はされずawkに
$1>$TMPTIME
という文字列を渡します。
これをawkが解釈するので、 $1 は 1つめのフィールドを表わしますが、 $TMPTIME はそのままです。
${TMPTIME} でも "$TMPFILE" でも同じです。awkにそのまま送られて、awk側で解釈しようとします。


方法の一つは TMPFILEの内容を反映させた文字列をawkへ送ることです。
set -x
を実行すると、以降は、シェルが展開した後の実際に実行するコマンドが出力されるようになります。
それで、awk に $1>"201030" というような感じで渡せるようにしましょう。
全体をダブルクオートにして、そのまま$やダブルクオートにしたい部分を\でエスケープします。

もう一つの方法は、awkの変数として定義することです。
awkの変数を実行時に定義する方法は、マニュアルや解説サイトを見ましょう。
    • good
    • 0
この回答へのお礼

kmee様、ありがとうございました。
ご教示いただいた内容に従い、awk内でシェルの変数を渡せるように定義し
正しく動作させることができました。実際の内容は
awk --assign にて定義しました。
改めて、再確認すべき点が多いことを認識いたしました。
今後ともよろしくお願いいたします。

お礼日時:2019/05/26 13:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!