早崎トップ 研究(気候気象) 研究(大気汚染) データリスト Linux Tips Mac Tips

Skeltons

スクリプトの雛型 (skelton)

自分が使う雛型スクリプト集. 出来る限り用途別に分類して置いたつもりだが,あまり細かい分類はしていない.

下記関連ページも参照

時間処理

 date コマンドを使った時間に関する繰り返し作業

date コマンドの使用方法・オプションの詳細は,

man date

にて調べること. see also 便利なコマンド # 時刻表記(ISO 8601形式)

よく使う時刻表記のシンプルな例は下記(Linux (CentOS)の場合):

$ date +%FT%T%z
2013-05-08T17:19:57+0900
$ date --rfc-3339=second
2013-05-08 17:20:00+09:00
$ date --rfc-3339=date
2013-05-08
$ date +%FT%T
2013-05-08T17:20:02
$ date +%FT%T%:z
2013-05-08T17:20:05+09:00
$ date +%Y%m%d
20130508

MacOS だと機能しない指定もある("%:z" が使えなかった).

date_loop01.sh

#!/bin/sh
#     1st release: 02 Oct. 2004
#     last update: 07 Jan. 2010

init_date=25Dec2009

LANG="C"

start_day=0
#end_day=366
end_day=3

inc=$start_day	# increment
while  [ $inc -le $end_day ] ; do

  n_date1=`\date --date="${init_date} +${inc}day" +"%Y%m%d"`    # 20091225
  n_date2=`\date --date="${init_date} +${inc}day" +"%d%b%Y"`    # ex. 25Dec2009
  n_date3=`\date --date="${init_date} +${inc}day" +"%m"`	# 2-digit month (01,02, ..., 12)
  n_date4=`\date --date="${init_date} +${inc}day" +"%d"`	# Day of Month
  n_date5=`\date --date="${init_date} +${inc}day" +"%Y"`	# 4-digit year
  n_date6=`\date --date="${init_date} +${inc}day" +"%j"`	# DOY
  n_date7=`\date --date="${init_date} +${inc}day" +"%B"`	# Full name of Month

  echo $inc  $n_date1  $n_date2   $n_date3 $n_date4 $n_date5 $n_date6 $n_date7

  inc=`expr $inc + 1`
done

date_loop02.sh

#!/bin/sh
#     1st release: 02 Oct. 2004
#     last update: 07 Jan. 2010

LANG="C"

s_hh=00
s_yyyymmdd=20091230     # sample start date (00UTC 30 Dec. 2009)

inc_hr=6	# increment in hours
#max_integ_hr=192      # Max. of integration time in hours
max_integ_hr=84       # Max. of integration time in hours

s_yyyy=`echo $s_yyyymmdd | cut -c 1-4`
s_mm=`echo $s_yyyymmdd | cut -c 5-6`
s_dd=`echo $s_yyyymmdd | cut -c 7-8`
echo -e "\t Initial date/time = ${s_hh} UTC ${s_yyyy} ${s_mm} ${s_dd}"
echo -e "\t Max. integration time = ${max_integ_hr}-hour"

cnt=0
integ_hr=0
yyyymmdd=$s_yyyymmdd
while  [ $integ_hr -le $max_integ_hr ] ; do
  n_date1=`\date --utc --date="${s_hh}UTC ${s_yyyymmdd} +${integ_hr} hour" +"%Y%m%d_%H"`
  echo "No., Integ hr, YYYYMMDD_HH = $cnt  $integ_hr  $n_date1"

  cnt=`expr $cnt + 1`
  integ_hr=`echo "$integ_hr + $inc_hr" | bc -q`
done

date_loop03.sh

#!/bin/sh
#     1st release: 02 Oct. 2004
#     last update: 21 Mar. 2010

LANG="C"

s_yyyymmddhh=2007033100     # sample start date (00UTC 30 Dec. 2009)
e_yyyymmddhh=2007040223     # sample start date (00UTC 30 Dec. 2009)

inc_hr=3	# increment in hours

s_yyyy=`echo $s_yyyymmddhh | cut -c 1-4`
s_mm=`echo $s_yyyymmddhh | cut -c 5-6`
s_dd=`echo $s_yyyymmddhh | cut -c 7-8`
s_hh=`echo $s_yyyymmddhh | cut -c 9-10`
s_yyyymmdd=`echo $s_yyyymmddhh | cut -c 1-8`

e_yyyymmdd=`echo $e_yyyymmddhh | cut -c 1-8`

echo -e "\t Initial date/time = ${s_hh} UTC ${s_yyyy} ${s_mm} ${s_dd}"
echo -e "\t End date/time = ${e_hh} UTC ${e_yyyy} ${e_mm} ${e_dd}"

cnt=0
yyyymmddhh=$s_yyyymmddhh
while  [ $yyyymmddhh -le $e_yyyymmddhh ] ; do
  yyyy=`echo $yyyymmddhh | cut -c 1-4`
  mm=`echo $yyyymmddhh | cut -c 5-6`
  dd=`echo $yyyymmddhh | cut -c 7-8`
  hh=`echo $yyyymmddhh | cut -c 9-10`
  yyyymmdd=`echo $yyyymmddhh | cut -c 1-8`

  n_date1=`\date --utc --date="${hh}UTC ${yyyymmdd}" +"%Y%m%d_%H"`
  echo "No., YYYYMMDD_HH = $cnt  $n_date1"

  cnt=`expr $cnt + 1`
  yyyymmddhh=`\date --utc --date="${hh}UTC ${yyyymmdd} +${inc_hr} hour" +"%Y%m%d%H"`
done

ここでは cut コマンドを使って year, month, day, hour などを切り出したが, シェル変数の部分文字列抜き出しを使うのもよい (参照: シェルスクリプトのメモ - シェル変数 (基本ルール) -). 個人の好み次第だが,部分文字列抜き出しの方が表示がシンプルに見える.

上記で cut を使ったのは,上記スクリプトを作成時に私が bash での シェル変数の部分文字列抜き出し方法を知らなかったため.

 日数計算

自作の WRF 実行スクリプトにおいて,計算開始日 & 終了日を指定(yyyymmdd 形式), 計算する日数を数える(シェル変数${period}を返す)ためのスクリプト.
以前にも類似スクリプトを作ったことあるが,所在を覚えてないので再作成(2018-05-15). web に置いておけば,検索で見つける事が可能.

  • 下記スクリプトで数える日数は,終了日を含まない. 00UTC $s_yyyymmdd から計算開始,00UTC $e_yyyymmdd にて計算終了,という指定方式とする.
  • 動作確認用に作ったシェルスクリプトなので,開始・終了日をスクリプト内で指定してある. 他プログラムでも利用するには,引数で与える関数にした方がラク.

##
s_yyyymmdd=20150301
e_yyyymmdd=20180405   # End at 00UTC of ${e_yyyymmdd}

e_yyyymmdd=20160405   # test01
e_yyyymmdd=20150405   # test02
e_yyyymmdd=20150302   # test03

if [ $s_yyyymmdd -gt $e_yyyymmdd ]; then
  echo "  *** (hysk) Error: Wrong start/end date. Stop."
  echo "    -> End date/time MUST set future date/time from start time"
  echo "    s_yyyymmdd = ${s_yyyymmdd} (Start date/time)"
  echo "    e_yyyymmdd = ${e_yyyymmdd} (End date/time)"
  exit 988
fi

s_yyyy=${s_yyyymmdd:0:4}
e_yyyy=${e_yyyymmdd:0:4}
  s_JD=$(\date --date="${s_yyyymmdd}" +%j)
  e_JD=$(\date --date="${e_yyyymmdd}" +%j)

if [ ${s_yyyy} -ne ${e_yyyy} ]; then
  # Case: Different year
  period=0
  yyyy=${s_yyyy}
  while [ $yyyy -lt $e_yyyy ]; do
    total_JD=$(\date --date="${yyyy}1231" +%j)

    case $yyyy in
    ${s_yyyy})
      period=$(echo "${total_JD} - ${s_JD} + 1" | bc -q)
      ;;
    *)
      period=$(echo "${period} + ${total_JD}" | bc -q)
      ;;
    esac

    yyyy=$(expr $yyyy + 1)
  done  
  period=$(echo "${period} + ${e_JD}" | bc -q)
else
  # Case: Same year
  period=$(echo "${e_JD} - ${s_JD}" | bc -q)
fi

  echo "*** final output ***"
  echo "  s_yyyymmdd, s_yyyy, s_doy  = ${s_yyyymmdd}, ${s_yyyy}, ${s_JD}"
  echo "  e_yyyymmdd, e_yyyy, e_doy  = ${e_yyyymmdd}, ${e_yyyy}, ${e_JD}"
  echo "    period = ${period}-days"

Fortran, Makefile

数値計算で使う Fortran 90/95およびそれをコンパイルするための Makefile に関するルール.

Fortran

書き方の大原則は 気象庁/気象研の 標準コーディングルール に従う. それと異なる私的ルールについては,F90/95 個人ルール参照.
文法,書式など忘れやすいものは F90 文法・書式・使用方法参照.

Makefile

Fortran90 個人メモ (hysk)以下にまとめた. See F90/95 Tips # Makefile 関連ルール

基本シェルスクリプト

シェルスクリプトの(私的な)原則に関する情報. 個別事項とその詳細解説はか,既存の情報があるのでリンク先を示す.
See シェルスクリプトメモ (hysk)

#!/bin/bash
#
#   1st release: 2099-12-31
#   M. Hayasaki, Jr. (???)
source $HOME/bin/function/chk_dir_file

work_ram=/dev/shm/$$
mkdir -p $work_ram ; pushd $work_ram

tmp01=${work_ram}/tmp01_$$.txt
tmp_list=" $tmp01 "


(some commands...)


popd ; \rm -rf $work_ram
exit

GMT

参照: GMTサンプルスクリプト集(hysk テキスト版), GMTサンプルスクリプト集(hysk サムネイル版)

画像 説明 スクリプト
main_Japan_Ja 日本列島主要4島&沖縄本島周辺 Japan_Ja.gmt
Iceland 大西洋北東部〜ヨーロッパ,アフリカ大陸北部 Iceland.gmt

 日本国内の地域別地図

地方別

地方別の白地図に大気汚染常時監視局の位置(2002年時点)を表示. ページ表示が重くなるので,画像は九州のみ表示.PDF は未作成. スクリプト;
北海道(東部), 北海道(北部), 北海道(西部), 東北(北部), 東北(南部), 関東, 中部, 近畿, 近畿~東海, 中国地方(東部), 中国地方(西部,東九州〜四国西部を含む), 九州, 九州(北西部,対馬・壱岐を含む),

Kyushu

  日本列島全体

主要4島拡大版

南西諸島は図の右下に挿入. 主要4島(北海道,本州,四国,九州)とは縮尺が異なるので注意. 地上観測所データ(大気汚染常時監視局,気象庁AMeDASなど)の空間分布を示すのに使用. スクリプト; PDF

Japan_Ja

日本列島全域

白地図. 縦置き(南北方向に広域な方)では,海域が大部分を占めるので陸上データのプロットには不向き. Radar AMeDAS や客観解析気象データなどの作図には手頃か.

wide_Japan_Ja wide_Japan_Ja02

日本の全地域,ただし高層気象ゾンデ観測点とWINDAS観測点を図示(2015年5月時点の観測点)
GMTを使った study area 作図サンプルとしても参考になるかも. スクリプト; PDF

pos_WINDAS

 ユーラシア大陸北東部,東アジア,モンゴル

ユーラシア大陸北東部から段階的に作図範囲を狭めたもの. 大陸からの寒気吹き出しや黄砂関連の研究で使用.

1つの作図スクリプト(EAsia-Japan_Js.gmt) で作成. スクリプト内部で4種の作図範囲を設定してある.

Js01

Js02

Js03

Js04

  北半球中・高緯度(20N 以北,ポーラーステレオ図法)

NH-20N script

 その他

北東大西洋〜ヨーロッパ,アフリカ大陸北部

アイスランドの火山噴火(2010年4月中旬)時の航空機運航停止期間中に,解析サンプル用として作成. 結局解析してないが.

Iceland script

中米(メキシコ合衆国)

Mexico script

grads

See also GrADS メモ(hysk)

  気候値(長期平均値.目安:30年間)の作成

例として,ジオポテンシャル高度 (varname = hgt) の月平均値(1979-2011年) のデータがあるとする.

この期間の月別気候値(長期平均値.ここでは,平均期間を1982-2009年とする)を GrADS内で作成し,各月の平年偏差を表示したい... という場合は,以下のようにする:

'set time jan1982 dec1982'
'define hgtclim = ave(hgt, t+0, t=372, 1yr)'
'modify hgtclim seasonal'
'set t 1 last'
'define anom = hgt - hgtclim'

データは1979年1月から存在しているが,平均値は1982年1月から計算したい,という場合. t=372 は,2009年12月の番号になる. もしデータ存在期間と平年値の計算期間が同一(1979-2011年,合計33-year,396-month)なら, もう少し単純な表記になる.


'set t 1 12'
'define hgtclim = ave(hgt, t+0, t=396, 1yr)'
'modify hgtclim seasonal'
'set t 1 last'
'define anom = hgt - hgtclim'

 参考: 気候値作成

更新履歴

Date Changes
2018-05-15 時間処理関連で,開始日・終了日を与えて日数を返す関数 (901_count_days.sh)を追加. WRFの計算期間をスクリプト内で計算するため.
2016-02-27 ページ内の参照用IDを付け替え. 番号付けのルールは, Linux tips (hysk) # 自分専用ルール・HTML に従う.
2010-01-07 多分,この日に記載開始. date コマンドのサンプルを作ったのが最初だと思う.