[ 岡山大学 | 理学部 | 地球科学科 | 地球および惑星大気科学研究室 ]

2020年度 大気科学演習1

シェルスクリプト

練習問題1ー1

1 から 1024 の数字を順番に表示する

1
2
3
...
1023
1024

ヒント

$ seq 1 1024

練習問題1ー1a

3 から 6 の数字を順番に表示する

3
4
5
6

ヒント1

n + 2
n=0
while [ $n -lt 4 ]; do
  n=$(( n + 1 ))
  a=$(( n + 2 ))
  echo $a
done

シェルスクリプトにおいて = の意味は,右辺の値を左辺に代入する,である(「n = n + 1 は間違ってる」とか言わないように).

ヒント2

a_n+1 = a_n + 1
b=$(( a + 1 ))
n=1
b=3
echo $b
while [ $n -lt 4 ]; do
  n=$(( n + 1 ))
  a=$b
  b=$(( a + 1 ))
  echo $b
done
n=1
b=3
echo $b
while [ $n -lt 4 ]; do
  n=$(( n + 1 ))
  b=$(( b + 1 ))
  echo $b
done

練習問題1ー1b

5 から 2 の数字を順番に表示する

5
4
3
2

ヒント

練習問題1ー1c

数列

11
14
17
...
98


練習問題1ー2

数列の和を計算する

ヒント1

n=0
while [ $n -lt 10 ]; do
  n=$(( n + 1 ))
  a=$(( 2 * n ))
done
n=0
s=0
while [ $n -lt 10 ]; do
  n=$(( n + 1 ))
  a=$(( 2 * n ))
  s=$(( s + a ))
done
echo $s

ヒント2

練習問題1ー2a

数列の和を計算する

答え合わせ


練習問題1ー3

九九の表を作るスクリプトを書く.

以下のような出力ができたらよい.

1  2  3  4  5  6  7  8  9
2  4  6  8 10 12 14 16 18
3  6  9 12 15 18 21 24 27
4  8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81

とりあえず,列が揃っていなくてもよい(ちょっとした小技を知っていると列を揃えるのは簡単であるが).

ヒント1

echo Hello
echo World

改行しないようにするにはオプション -n をつける

echo -n Hello
echo -n World
echo ' '

ヒント2

1 1
1 2
1 3
2 1
2 2
2 3

と出力するスクリプトを書き換えることを考える

#/bin/bash
i=0
while [ $i -lt 2 ]; do
  i=$(( i + 1 )
  j=0
  while [ $j -lt 3 ]; do
    j=$(( j + 1 ))
    k=$(( i * j ))
    echo $k
  done
done
#/bin/bash
i=0
while [ $i -lt 2 ]; do
  i=$(( i + 1 )
  j=0
  while [ $j -lt 3 ]; do
    j=$(( j + 1 ))
    k=$(( i * j ))
    echo -n $k
  done
  echo
done
#/bin/bash
i=0
while [ $i -lt 2 ]; do
  i=$(( i + 1 )
  j=0
  while [ $j -lt 3 ]; do
    j=$(( j + 1 ))
    k=$(( i * j ))
    echo -n ' '
    echo -n $k
  done
  echo
done


練習問題1ー4

Fibonacci sequence (フィボナッチ数)

F_0 = 0, F_1 = 1
F_{n+2} = F_n + F_{n+1}

ヒント

c=$(( a + b ))
n=1
c=0
echo $c
n=$(( n + 1 ))
b=$c
c=1
echo $c
n=$(( n + 1 ))
a=$b
b=$c 
c=$(( a + b ))
echo $c
n=$(( n + 1 ))
a=$b
b=$c 
c=$(( a + b ))
echo $c

スクリプトのちょっとやりすぎな気もする解説

n=1
c=0
echo $c
n=$(( n + 1 ))
b=$c
c=1
echo $c
while [ $n -lt 10 ]; do
  n=$(( n + 1 ))
  a=$b
  b=$c
  c=$(( a + b ))
  echo $c
done

練習問題1ー4a

トリボナッチ数

T_0 = T_1 = 0, T_2 = 1
T_{n+3} = T_n + T_{n+1} + T_{n+2}

練習問題1ー4b

テトラナッチ数

T_0 = T_1 = T_2 = 0, T_3 = 1
T_{n+4} = T_n + T_{n+1} + T_{n+2} + T_{n+3} 

#練習問題1ー4c

Fibonacci sequence (フィボナッチ数)

ヒント

$(( x + y ))

から

$( echo  "$x + $y" | bc )

に変更してみる.


練習問題1ー5

/work2/atmos/data/skymonitor 以下に保存されている,スカイモニターで撮影された画像の枚数を数える

20161014  255
20161015  1092
20161016  1093
20161017  1362
20161107  351
20161108  426
...

ヒント

#!/bin/bash                                                                     
days=$( ls /work2/atmos/data/skymonitor/2016/10 )
for yyyymmdd in $days ; do
  echo $yyyymmdd
done

実行したら

20161014
20161015
20161016
20161017
#!/bin/bash                                                                     
days=$( ls /work2/atmos/data/skymonitor/2016/10 )
for yyyymmdd in $days ; do
  num=$( ls /work2/atmos/data/skymonitor/2016/10/${yyyymmdd}/*.jpg | wc -l )
  echo $yyyymmdd $num
done

実行したら

20161014 255
20161015 1092
20161016 1093
20161017 1362
yyyy=2016
mm=10
days=$( ls /work2/atmos/data/skymonitor/${yyyy}/${mm} )
for yyyymmdd in $days ; do
  num=$( ls /work2/atmos/data/skymonitor/${yyyy}/${mm}/${yyyymmdd}/*.jpg | wc -l )
  echo $yyyymmdd $num
done
#!/bin/bash                                                                     
yyyy=2016
months=$( ls /work2/atmos/data/skymonitor/${yyyy} )
for mm in $months ; do
  days=$( ls /work2/atmos/data/skymonitor/${yyyy}/${mm} )
  for yyyymmdd in $days ; do
    num=$( ls /work2/atmos/data/skymonitor/${yyyy}/${mm}/${yyyymmdd}/*.jpg | wc -l )
    echo $yyyymmdd $num
  done
done
#!/bin/bash                                                                     
years=$( ls /work2/atmos/data/skymonitor )
for yyyy in $years ; do
  months=$( ls /work2/atmos/data/skymonitor/${yyyy} )
  for mm in $months ; do
    days=$( ls /work2/atmos/data/skymonitor/${yyyy}/${mm} )
    for yyyymmdd in $days ; do
      num=$( ls /work2/atmos/data/skymonitor/${yyyy}/${mm}/${yyyymmdd}/*.jpg | wc -l )
      echo $yyyymmdd $num
    done
  done
done
ls: cannot access '/work2/atmos/data/skymonitor/2019/07/20190705/*.jpg': No such file or directory

のようなメッセージが吐き出されたかもしれない.メッセージをみたらだいたいわかると思うが,指定したファイルは存在しないと言われている.ディレクトリはあるけどファイルがない,という場合があるということである.

num=$( ls /work2/atmos/data/skymonitor/${yyyy}/${mm}/${yyyymmdd}/*.jpg 2>/dev/null | wc -l )

練習問題1ー5a

2016 21682
2017 499525
2018 428194
2019 381291
2020 388234

ヒント

num=$( ls /work2/atmos/data/skymonitor/${yyyy}/*/*/*.jpg | wc -l )

のようなことをしたかもしれない.理屈は正しくて,これでうまくいくべきなのであるが,実際には

Argument list too long

のようなメッセージが表示されたりして,うまっくいかない.メッセージを見たら察しはつくと思うが,これはファイルの数が多すぎてダメと言われている.それくらいなんとかしてくれと思わなくもないが,ダメなものはダメなので,違う方法(小分けにして溢れないようにして,足し算する)を考えてください.

#%練習問題1ー5b

01 164756
02 160271
03 145159
04 134472
05 104755
06 129331
07 156557
08 176002
09 145356
10 133105
11 122978
12 146184

#%練習問題1ー5c

00 71951
01 71851
02 71864
03 71826
04 71806
05 71753
06 71645
07 71435
08 71431
09 71480
10 71579
11 71465
12 71329
13 71061
14 70814
15 70750
16 70846
17 71371
18 71795
19 72216
20 72336
21 72220
22 72088
23 72014




Last Updated: 2020/10/29, Since: 2019/10/24.
This page is generated by Makefile.rd2html.