Created
July 18, 2012 12:41
-
-
Save trmtsy/3135987 to your computer and use it in GitHub Desktop.
昔やったシェルスクリプトの問題
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
シェルスクリプト問題 | |
はじめに | |
シェルスクリプトでは算術演算にexprコマンドを使います。 | |
# exprコマンドで実行した結果をaの変数に格納する | |
a=`expr 1+2` | |
またbashの機能として | |
a=$(( 1 + 2 )) | |
のように $(()) で囲われた部分を算術演算することもできます。 | |
今回はexprコマンドを使用します。 | |
■問1 変数を3つ使用し、四則演算の減算を行うスクリプトを作成せよ。 | |
※ 変数は a=10 、 b=5 、cには a-b の結果を格納すること。 | |
#!/bin/bash | |
a=10 | |
b=5 | |
c=`expr $a - $b` | |
echo $c | |
【 実行結果 】 | |
$ ./1.sh | |
5 | |
変数に値を代入し、exprコマンドを使って計算した結果をcの中に格納して出力します。 | |
変数名の先頭に$(ダラー)を付けることで変数に格納している値を使用することができます。 | |
■問2 変数を使用し、キーボードから入力した文字列を表示させるスクリプトを | |
作成せよ | |
※ 変数aを使用すること | |
#!/bin/bash | |
echo "入力" | |
read a | |
echo "出力" | |
echo $a | |
【 実行結果 】 | |
$ ./2.sh | |
入力 | |
あいうえお | |
出力 | |
あいうえお | |
readコマンドは標準入力からデータを読み込みます。ここでは読み込んだデータをaに格納し、echoコマンドを使って出力します。 | |
■問3 現在の日時と時間を表示するスクリプトを作成せよ。 | |
※ 日、月、年、時間の順で表示させること | |
※ 日、月、年、時間の間には、「、」を表示させること | |
#!/bin/bash | |
date "+%d日、%m月、%Y年、時刻%T" | |
【 実行結果 】 | |
$ ./3.sh | |
26日、07月、2011年、時刻11:18:48 | |
時刻を表示するにはdateコマンドを使います。dateコマンドに+から始まる引数を渡すことで指定したフォーマットで出力することができます。 | |
%を使って指定したフィールドの値を取得することができます。 | |
%d 月内通算日数 (01..31) | |
%m 月 (01..12) | |
%Y 年 (1970...) | |
%T 時刻、24 時間 (hh:mm:ss) | |
dateコマンドの詳しい使い方はman dateコマンドで見ることができます。 | |
■問4 if文を使用し、実行時点の午前/午後の判別を行うスクリプトを作成せよ。 | |
#!/bin/bash | |
hour=`date "+%H"` | |
# 12より小さい時の処理 | |
if [ $hour -lt "12" ]; then | |
echo "午前です" | |
# 12以上の時の処理 | |
elif [ $hour -ge "12" ]; then | |
echo "午後です" | |
fi | |
【 実行結果 】 | |
※ 実行例ではdateコマンドで日付を変更しています。日付変更を許可されているユーザで実行する必要があります。ここではrootになっています。 | |
# date | |
2011年 7月 25日 月曜日 11:00:19 JST | |
# ./4.sh | |
午前です | |
# date -s "07/25 22:00 2011" ←日付を設定しています。 | |
2011年 7月 25日 月曜日 22:00:00 JST | |
# ./4.sh | |
午後です | |
dateコマンドの引数で ”+%H” を渡します。 | |
%H 時 (00..23) | |
変数hourには現在の時刻00~23が入ります。条件式でhourが12より小さければ ”午前です”、hourが12以上であれば ”午後です” と出力します。 | |
■問5 for文を使用し、1週間の間で、何日忙しいか表示させるスクリプトを作成せよ。 | |
※ 月曜日から日曜日にかけてyes / no で入力できるようにすること | |
#!/bin/bash | |
# 忙しいかった日をカウントする変数 | |
busyday=0 | |
for week in 月 火 水 木 金 土 日; do | |
echo "$week曜日は忙しかったですか?(yes/no)" | |
read busy | |
case $busy in | |
yes) busyday=`expr $busyday + 1`;; | |
no) continue;; | |
esac | |
done | |
echo "$busyday日、忙しい日がありました。" | |
【 実行結果 】 | |
$ ./5.sh | |
月曜日は忙しかったですか?(yes/no) | |
yes | |
火曜日は忙しかったですか?(yes/no) | |
no | |
水曜日は忙しかったですか?(yes/no) | |
yes | |
木曜日は忙しかったですか?(yes/no) | |
no | |
金曜日は忙しかったですか?(yes/no) | |
no | |
土曜日は忙しかったですか?(yes/no) | |
no | |
日曜日は忙しかったですか?(yes/no) | |
yes | |
3日、忙しい日がありました。 | |
まずカウント用変数busydayを用意します。次にfor文のリストに月~日曜日までの7つの値を用意します。for文はリストの値をweek変数に格納してリストが終わるまで実行します。 | |
readコマンドでyes / noの入力をbusy変数に格納します。 | |
次にcase文を使ってbusy変数がyesの場合はbusydayをインクリメントして、noの場合はcontinueで処理を続けます。 | |
■問6 if文を使用し、入力された値を100未満、100以上1000未満、1000以上かを | |
判断するスクリプトを作成せよ。 | |
※ 「100未満です」、「100以上1000未満です」、「1000以上です」のいずれかを返すこと | |
#!/bin/bash | |
echo "数値を入力" | |
read num | |
if [ $num -lt "100" ]; then | |
echo "100未満です" | |
elif [ $num -ge "100" ] && [ $num -lt "1000" ]; then | |
echo "100以上1000未満です" | |
elif [ $num -ge "1000" ]; then | |
echo "1000以上です" | |
fi | |
【 実行結果 】 | |
$ ./6.sh | |
数値を入力 | |
99 | |
100未満です | |
$ ./6.sh | |
数値を入力 | |
100 | |
100以上1000未満です | |
$ ./6.sh | |
数値を入力 | |
999 | |
100以上1000未満です | |
$ ./6.sh | |
数値を入力 | |
1000 | |
1000以上です | |
変数numに入力された値が条件式に当てはまるものを出力します。 | |
if [ $num -lt "100" ]; | |
numが100以下で未満であれば真 | |
elif [ $num -ge "100" ] && [ $num -lt "1000" ]; | |
numが100以上 かつ numが1000未満であれば真 | |
elif [ $num -ge "1000" ]; | |
numが1000以上であれば真 | |
■問7 while文を使用し、入力された値をデクリメントしながら表示し、5になった時点で | |
終了するスクリプトを作成せよ | |
※ 「5」未満の入力はエラーメッセージを表示すること | |
#!/bin/bash | |
echo "5以上の数値を入力してください" | |
read num | |
if [ $num -ge "5" ]; then | |
echo "出力" | |
while [ $num -ge "5" ]; do | |
echo "$num" | |
num=`expr $num - 1` | |
done | |
echo "終わり" | |
else | |
echo "5以上の数値ではありません。" | |
fi | |
【 実行結果 】 | |
$ ./7.sh | |
5以上の数値を入力してください | |
4 | |
5以上の数値ではありません。 | |
$ ./7.sh | |
5以上の数値を入力してください | |
15 | |
出力 | |
15 | |
14 | |
13 | |
12 | |
11 | |
10 | |
9 | |
8 | |
7 | |
6 | |
5 | |
終わり | |
変数numに格納された値が5以上であれば処理を実行します。 | |
while文でnumの値が5より小さくなるまでnumの値を出力しながらデクリメントしていきます。 | |
numが5より小さくなれば処理を終了します。 | |
■問8 until文を使用し、5から1まで順に表示していくスクリプトを作成せよ。 | |
#!/bin/bash | |
count=5 | |
until [ $count -eq "0" ]; do | |
echo $count | |
count=`expr $count - 1` | |
done | |
【 実行結果 】 | |
$ ./8.sh | |
5 | |
4 | |
3 | |
2 | |
1 | |
まず変数countに5を代入します。until文では条件が成立しない間ループを繰り返します。 | |
なのでcount変数が0になるまでcount変数を出力しながらデクリメントしていきます。 | |
countが0になれば条件が成立するのでループを終了します。 | |
■問9 変数numを乱数で宣言し、入力した値が同じになるまで繰り返すスクリプトを | |
作成せよ。While文を使用すること | |
※ 入力値が乱数より大きいか小さいかを表示させること | |
#!/bin/bash | |
num=`expr $RANDOM % 10` | |
echo "数当てゲーム" | |
while : | |
do | |
echo "0~9の数値を入力してください" | |
read inputNumber | |
if [ $inputNumber -eq $num ]; then | |
echo "正解!$numでした" | |
break | |
elif [ $inputNumber -gt $num ]; then | |
echo "もっと小さい" | |
elif [ $inputNumber -lt $num ]; then | |
echo "もっと大きい" | |
fi | |
done | |
【 実行結果 】 | |
$ ./9.sh | |
数当てゲーム | |
0~9の数値を入力してください | |
4 | |
もっと大きい | |
0~9の数値を入力してください | |
7 | |
もっと小さい | |
0~9の数値を入力してください | |
6 | |
もっと小さい | |
0~9の数値を入力してください | |
5 | |
正解!5でした | |
bashではRANDOMという乱数を生成する変数が用意されています。RANDOMは0から32767のランダムな値を生成します。 | |
変数numにはRANDOMで取得した値を10で割った余りが格納されます。なのでnumには0~9までの値が格納されます。 | |
この例では正解するまでwhileで処理を繰り返し、正解するとbreakでループを抜けます。 | |
whileで無限にループさせたいときには | |
while : ←コロン | |
do | |
done | |
while [ 1 ] | |
do | |
done | |
などと書きます。 | |
変数inputNumber に0から9までの入力された値を読み込みます。 | |
if [ $ inputNumber -eq $num ]; | |
inputNumber とnumが一致した場合は”正解!$numでした”と出力した後、breakしてループを抜けます。 | |
elif [ $ inputNumber -gt $num ]; | |
inputNumber がnumより大きい場合は”もっと小さい”と出力します。 | |
elif [ $ inputNumber -lt $num ]; | |
inputNumber がnumより小さい場合は”もっと大きい”と出力します。 | |
■問10 カレントディレクトリに格納されているものを表示させるスクリプトを作成せよ。 | |
#!/bin/bash | |
ls ./ | |
【 実行結果 】 | |
$ ./10.sh | |
1.sh 11.sh 3.sh 5.sh 7.sh 9.sh chmod755.sh | |
10.sh 2.sh 4.sh 6.sh 8.sh age.sh test.sh | |
カレントディレクトリはユーザが現在作業を行っているディレクトリのことを指します。Linuxなどでカレントディレクトリを表すには ./ を使います。なのでls ./ とすればカレントディレクトリの情報を見ることができます。 | |
■問11 四則演算をメニュー形式で行えるスクリプトを作成せよ。 | |
#!/bin/bash | |
while : | |
do | |
echo "四則演算 1)加算 2)減算 3)乗算 4)除算 5)終了" | |
read calc | |
case $calc in | |
1) | |
echo "加算を始めます" | |
echo "最初の値を入力" | |
read num1 | |
echo "次の値を入力" | |
read num2 | |
answer=`expr $num1 + $num2` | |
echo "$num1 + $num2 = $answer です" | |
;; | |
2) | |
echo "減算を始めます" | |
echo "最初の値を入力" | |
read num1 | |
echo "次の値を入力" | |
read num2 | |
answer=`expr $num1 - $num2` | |
echo "$num1 - $num2 = $answer です" | |
;; | |
3) | |
echo "乗算を始めます" | |
echo "最初の値を入力" | |
read num1 | |
echo "次の値を入力" | |
read num2 | |
answer=`expr $num1 '*' $num2` | |
echo "$num1 x $num2 = $answer です" | |
;; | |
4) | |
echo "除算を始めます" | |
echo "最初の値を入力" | |
read num1 | |
echo "次の値を入力" | |
read num2 | |
answer=`expr $num1 '/' $num2` | |
echo "$num1 / $num2 = $answer です" | |
;; | |
5) break;; | |
esac | |
done | |
echo "終了しました" | |
【 実行結果 】 | |
$ ./11.sh | |
四則演算 1)加算 2)減算 3)乗算 4)除算 5)終了 | |
1 | |
加算を始めます | |
最初の値を入力 | |
3 | |
次の値を入力 | |
4 | |
3 + 4 = 7 です | |
四則演算 1)加算 2)減算 3)乗算 4)除算 5)終了 | |
2 | |
減算を始めます | |
最初の値を入力 | |
10 | |
次の値を入力 | |
3 | |
10 - 3 = 7 です | |
四則演算 1)加算 2)減算 3)乗算 4)除算 5)終了 | |
3 | |
乗算を始めます | |
最初の値を入力 | |
5 | |
次の値を入力 | |
5 | |
5 x 5 = 25 です | |
四則演算 1)加算 2)減算 3)乗算 4)除算 5)終了 | |
4 | |
除算を始めます | |
最初の値を入力 | |
10 | |
次の値を入力 | |
2 | |
10 / 2 = 5 です | |
四則演算 1)加算 2)減算 3)乗算 4)除算 5)終了 | |
5 | |
終了しました | |
メニュー形式で計算方法を選べるようにします。calc変数に入力された値を条件に処理をcase文によって分けています。 | |
計算方法としてはreadコマンドにてnum1、num2の値を読み込み、exprコマンドにて計算した結果をanswer変数に代入し出力しています。 | |
注意しなければならないのは乗算と、除算を意味する*(乗算) / (除算)は特殊文字として扱われるのでシングルクォートで囲って文字をエスケープしなければなりません。 | |
乗算 answer=`expr $num1 '*' $num2` | |
除算 answer=`expr $num1 '/' $num2` | |
この実行例ではメニューで5が選択されるまでwhile文にて処理を繰り返します。 | |
以上で終わります。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment