crontabをCSV形式で出力したいです。

まずは以下行をご覧ください。サーバのcrontabのとある1行です。
00,10,20,30,40,50 * * * * sh /home/hoge/foo.sh clean all > /dev/null 2>&1

これを以下のようにCSVデータ化したいです。
sh /home/hoge/foo.sh clean all > /dev/null 2>&1,"00,10,20,30,40,50:*","* * *"

で、これをawkでやろうとしたところ、
$ cat crontab | awk 'BEGIN{OFS=","} {print $6,$7,$8,$9,$10,$2":"$1,$3,$4,$5}'
sh,/home/hoge/foo.sh,clean,all,>,*:00,10,20,30,40,50,*,*,*
と、スクリプト指定のところはオプションまでカンマ区切りになってしまい、また10分おきに動かしているためのカンマ指定とごっちゃになってしまい、
$ cat crontab | awk 'BEGIN{OFS=","} {print $6,$7,$8,$9,$10,$2":"$1,"$3,$4,$5"}'
sh,/home/hoge/foo.sh,clean,all,>,*:00,10,20,30,40,50,$3,$4,$5
…とまぁこんな感じになってしまい上手くいきません。
awkについてはほとんど知識、コーディングしたことがないため、詰まってしまっています。
ちなみにawk縛りと言うのはありません。perlやsedでも、出来るなら手段は問わないです。
よろしくお願いいたします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/08/31 08:30:13
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.1

回答回数4974ベストアンサー獲得回数2154

ポイント500pt

awk でやると、こんな感じでしょうか。

#! /usr/bin/sh -f
crontab -l | awk '
{
    t = "\"" $1 ":" $2 "\""
    d = "\"" $3 " " $4 " " $5 "\""
    $1 = $2 = $3 = $4 = $5 = ""
    sub(/^     /, "")
    print $0 "," t "," d
}
'

時分の順番が、質問文では二種類書いてあったので、crontab に合わせて分→時としてあります。
ワンライナーでも書けますが、ちょっと苦しい感じですかね。



追記です。


$1、$2 ... は、入力行を IFS で区切ったものです。
$0 は、入力行そのものを表すのですが、$1 などを変更すると、その内容が反映されます。

$0 == $1 IFS $2 IFS $3 IFS $4 ...

という関係が、常に成り立ってます。

まず、いくつ空白が入ってるかわからない crontab のコマンドの内容を取得するためには、個数が決まっている時刻指定のところを消しちゃえば良いじゃん、ってところから入りました。

$1 = $2 = $3 = $4 = $5 = ""

が、時刻指定の最初の五つの項目を消してます。
五個目までを空文字列にすると、$0 は、その内容を反映して

$0 == "     sh /home/hoge/foo.sh clean all > /dev/null 2>&1"

となってます。
空文字列五個を、OFS の空白が結合しているので、先頭に、欲しくない空白五つが付いた状態になってます。
その行頭の空白五つを切り取るのが、以下の行です。

sub(/^     /, "")

これで、コマンドの表現は手に入りました。
後は、消してしまった時刻を表す表現を、前もって別の変数に入れておくだけです。

まだ、他に聞きたいことがあれば、何なりと。
分かる範囲で答えます。

他5件のコメントを見る
id:Marin_MTB

ありがとうございます。とても参考になります。
ちょっとawkから離れるかもですが、更に教えてください。
for文で定義された変数が表示されず、困っております。例えば、
for FILE in `ls /var/spool/cron`
do
echo USER=${FILE}
cat /var/spool/cron/$FILE | awk '{print $1 "," '${FILE}'}'
done
と言う文を作成し、実行しました。
その結果、本来$FILEで定義された(例えばrootとか)が表示されるはずが表示されません。
> USER=root
> */5,
という感じでawkにfor文で定義された変数$FILEが反映されません。
for文の前に定義された変数についてはどうも認識するようなのですが…。
シェル変数?とは呼ばないかも知れませんが、echoでは表示されるため、一見有効そうに思われるのですが…。

2012/08/28 18:52:09
id:a-kuma3

試してないので想像で書いてます。

シェル変数が展開された後は、こうなってます。

awk '{print $1 "," root}'

awk は、root という文字列ではなく、root という変数を print しているのだと思います。
cat ~ の行を、以下のようにしてみてください。

cat /var/spool/cron/$FILE | awk '{print $1 "," "'${FILE}'"}'

分かりにくいかもしれませんが、${FILE} を挟んでいるシングルクォートの前後にダブルクォートを入れてます。
シェル変数が展開された後に、以下のような感じに展開されるイメージです。

awk '{print $1 "," "root"}'
2012/08/28 21:17:48

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません