Bash ファイルの名前が時間であるデータを取り出す

ファイルやディレクトリの名前が時間である場合に、ある期間内、そのファイルを読み込んで計算して出力する際、何度もプログラムのPATHを変えるのはとても面倒なことです。

仮定

例として、このようなディレクトリやファイルであるとします。

sampledataディレクトリに年のディレクトリがあり、その下に月のディレクトリ、その下に日のディレクトリがあるという想定です。

$ pwd
sampledata/2021/11/22/
$ ls
0000.bin    0600.bin    1200.bin    1800.bin
0100.bin    0700.bin    1300.bin    1900.bin
0200.bin    0800.bin    1400.bin    2000.bin
0300.bin    0900.bin    1500.bin    2100.bin
0400.bin    1000.bin    1600.bin    2200.bin
0500.bin    1100.bin    1700.bin    2300.bin

ここの例では、2021年11月22日の1時間ごとのデータが入っています。

同様に他のディレクトリでも1時間ごとのデータが入っていることを想定しています。

繰り返し処理で一度のプログラムだけで2000年1月1日00時から2021年12月31日23時までのファイルを一つずつ読み込んで実行する方法を紹介します。

今回の記事では、シェル(bash)を使います。

プログラム

実行する場所はどこでも問題ありません。PATHを指定していますので…

またこのプログラムでは、計算を実行するコードはPythonを想定していますが、どの言語でも大丈夫です。

#! /bin/bash
dateb=2000010100; datee=2021123123;
out='data.dat'
datec=$dateb
while [ $datec -le $datee ]; do
    yy=`echo $datec | cut -b1-4`
    mm=`echo $datec | cut -b5-6`
    dd=`echo $datec | cut -b7-8`
    hh=`echo $datec | cut -b9-10`
    cdatec="$yy/$mm/$dd $hh:00:00"
    if [ -e $out ];then
        rm -f $out
    fi
   ln -sf ${yy}/${mm}/${dd}/${hh} $out #data path
    python sample.py
    
    yy=`date -d "$cdatec 1hour" '+%Y'`
    mm=`date -d "$cdatec 1hour" '+%m'`
    dd=`date -d "$cdatec 1hour" '+%d'`
    hh=`date -d "$cdatec 1hour" '+%H'`
    datec=$yy$mm$dd$hh
done

解説

1行目のインタプリター(呪文)を書いて、スタート

2行目に変数datebと変数dateeがあります。datebには、開始時刻、dateeには終了時刻を入れましょう。

例として、2004年8月24日13時にしたい場合は、2004082413とします。

3行目は、シンボリックリンクの名前の変数です。

シンボリックリンクについて詳しくはこちらから

5行目で繰り返し処理開始です。2行目に設定した、開始時刻から終了時刻まで繰り返し処理をします。

6行目から9行目までは、現在の時刻をそれぞれ年、月、日、時に分割し、変数に代入されています。

10行目のcdatecは、時刻を更新する際に後に用います。(17〜20行目)

11~13行目は、シンボリックリンクを削除しています。

14行目で、シンボリックリンクを作成しています。ここで、PATHを指定しています。上のコードは、実行するファイルのPATHの下にデータがあると想定しています。自身の環境に変更しましょう。

15行目でpythonファイルを実行。pythonファイルでは、以下のようにファイルを読み込みましょう。

with open('out.dat')as f:
    .....

17~20行目で時刻を更新します。上のコードでは、1時間先に時刻を更新しています。

そして、年、月、日、時に分割し、変数に代入されて、最終的にdatecに代入されています。