my備忘録 シリーズ 2つ目。
自分がスクリプトを書く際に「あの処理って、どう記述するんだっけ?」とあれこれ検索し直すことが度々あったので。作業効率化のために、一箇所にまとめてゆく予定。(新しいことを学ぶ度に随時追加)
- Linux標準(+α)のコマンドについても、簡単にまとめる。
- 複数コマンドの組み合わせ技や、(自分がやりたかった)極めて限定的な目的に対する(自分なりに見出した)解決策も載せる。
※応用範囲が狭いこと、当方の技量不足により必ずしも最適解とは限らないことにご留意ください。
※実際にコマンドを実行し、おかしな動作にならないか確認はしていますが、実行環境の違いや記載ミス等の理由により問題が発生する可能性がありますので、十分ご注意ください。
目次
I. 変数
- 1. 特殊変数
- 3. 変数の展開と結合
II. 制御構文
- 1. for ループ
- 2. if 構文
III. 入出力
IV. 応用事例
XXX.便利なコマンドいろいろ
- echo, printf
I. 変数
- 変数の宣言は基本的には必要ない。
- 変数への代入は
変数名=設定したい値
で行う。注意点として、代入演算子=
の前後にはスペースを空けずにstr='hoge'
,var=3.14
のように記述する必要がある。 - 変数の値を参照する際には
$
を頭につけて$変数名
で呼び出す。例:echo $var
-
declare
コマンドを用いると、変数のタイプを指定した上で宣言することもできる。
1. 特殊変数
変数 | 説明 |
---|---|
$? |
直前に実行されたコマンドの終了ステータス (数値) |
$0 |
現在実行されているコマンドの名前 |
$$ |
現在実行されているコマンドのプロセスID |
$# |
現在のスクリプトに渡された引数の個数 |
$@ |
現在のスクリプトに渡された全引数 (文字列) |
$1 , $2 , ..., ${10} , ... |
現在のスクリプトに渡された(数値) 番目の引数 |
echo "name='$0'"
echo "Nargs="$#
for i in $(seq $#); do
echo -n "arg_num=$i, "
eval "echo arg=\'\$${i}\'"
done
echo "args='$@'"
for arg in "$@"; do echo "arg='${arg}'"; done
> bash sample_args.sh 2 b と実行した結果
name='./sample_args.sh'
Nargs=2
arg_num=1, arg='2'
arg_num=2, arg='b'
args='2 b'
arg='2'
arg='b'
-
$@
と$*
の違い: -
より詳しい情報はこちらを参照。
2. 配列
3. 変数の展開と結合
変数展開 (parameter expansion)
- この機能を使うことで、変数文字列に対してさまざまな操作をすることができる。以下は、その一例。
str="fuga_fuwa_fuga" #対象文字列
#パターンマッチ部分の置換
echo ${str/a/o} #aをoに置換。結果: fugo_fuwa_fuga
#全てのパターンマッチ部分の置換
echo ${str//a/o} #aをoに置換。結果: fugo_fuwo_fugo
#先頭からマッチした部分の置換
echo ${str/#fuga/puwa} #結果: puwa_fuwa_fuga
#末尾からマッチした部分の置換
echo ${str/%fuga/puwa} #結果: fuga_fuwa_puwa
str="hoge_fuga_fuwa_fuga" #対象文字列
#前方最短一致削除(#以降の文字列パターンについて、前方最短一致する部分までを除去)
echo $(str#ho} #実行結果: ge_fuga_fuwa_fuga
echo $(str#*f} #実行結果: uga_fuwa_fuga
#前方最長一致削除(##以降の文字列パターンについて、前方最長一致する部分までを除去)
echo $(str##*f} #実行結果: uga
#後方最短一致削除 (%以降の文字列について、後ろから探索して最短一致パターンを除去)
echo ${str%_fuga*} #実行結果: hoge_fuga_fuwa
#後方最長一致削除: (%%以降の文字列について、後方から最長一致パターンを除去)
echo ${str%_fuga*} #実行結果: hoge
#置換構文による部分削除 (置換後文字列を空白にすることで削除を実現できる)
echo ${str%//_fuga/} #実行結果: hoge_fuwa
#置換構文による部分削除 (置換後文字列とのセパレーター'/'はなくても大丈夫っぽい)
echo ${str%/_fuwa} #実行結果: hoge_fuga_fuga
4. コマンドの実行結果を変数に代入する
II. 制御構文
1. for ループ
ループ変数は数値だけではなく、任意の文字列が指定できる。たとえば、ファイル名のリストに対して使うこともできるので便利。
#in の後に配置された文字列について、1つずつ取り出し、順番に処理を実行する
for i in {0..2}
do #"0 1 2"という文字列に対してループさせる
echo $i #なんらかのループ中に実行したい処理
done
for i in {0..2}; do echo $i; done
実行結果:
0
1
2
for i in a{b..d}e; do echo $i; done
実行結果:
abe
ace
ade
for i in {0..2}; #「ブレース展開」により、数列"0 1 2"を生成
for i in `seq 0 2`; #seq コマンドを利用し、数列を生成。`command`により実行結果を展開
for i in $(seq 0 2); #同上。「コマンド置換」 $(commnad)により実行結果を展開
for ((i=0; i<3; i++)); #「初期値,ループ条件,次ループ時の処理」を指定するおなじみの形式
for ((i=0; i<=2; i++)); #同上
-
ブレース展開
: ある規則にしたがって連続した文字列を生成する機能。(参考ページ)
複数ファイルに対してループ処理を実行する
for file in *; #カレントディレクトリを指定 (最も簡潔)
for file in ./*; #カレントであることを明示
for file in "$dir"/*; #ディレクトリを(変数によって)指定
for file in "$dir"/*.txt; #ファイル拡張子も指定 (.txtファイルについてループ)
for file in $(ls "$dir"/*.txt); #コマンドの実行結果を利用
for file in $(find "$dir" -type d); #コマンドを利用 (ディレクトリファイルについてループ)
2. if 構文
- 基本構文
-
[ ]
と[[ ]]
の違い
条件の指定
#or
#and
#複数組み合わせ
文字列の比較
数値の比較
ファイルの有無の確認
if [[ -e ./hoge ]]; #ファイル'./hoge'が存在すれば真 ('e'xist)
if [[ ! -e ./hoge ]]; #ファイル'./hoge'が存在しなければ真 (Not 'e'xist)
if [[ -f ./hoge ]]; #通常ファイルが存在するか ('f'ile)
if [[ -d ./hoge ]]; #ディレクトリが存在するか ('d'irectory)
if [[ -L ./hoge ]]; #シンボリックリンクが存在するか ('L'ink)
if [[ -s ./hoge ]]; #空でないファイルが存在するか
#-> ファイルが存在し、かつファイルサイズが非ゼロならば真 ('s'ize)
その他
恒真, 恒偽条件による制御
if true; then $(command); fi #常に実行される
if false; then $(command); fi #常に実行されない
スクリプトのある範囲について、実行する/しないを制御できるので、デバッグなど一時的な変更に便利
便利なコマンドいろいろ
echoコマンド
echo 文字列
やまびこ(echo)のように、入力された文字列をそのまま返す(出力する)。
ちょっとくわしい説明
オプション | 説明 |
---|---|
-n | 出力文字列の最後に改行しない |
-e |
エスケープシーケンス を解釈する |
echo "test"; echo 10 #基本
# test
# 10
str="tes"; echo $str #変数を出力
# tes
echo "test" 10 $str #複数出力
# test 10 tes
echo '$str' "$str" #クオーテーションによる違い(シングル内は文字列扱い、ダブル内は変数展開)
# $str tes
echo -n " a"; echo b #末尾の改行なし
# a b
echo -e " a\n"; echo b #改行コードの使用
# a
#
# b
echo $((3*5)); echo $(printf "%03d" 7) #コマンドの実行結果を出力
# 15
# 007
printfコマンド
printf フォーマット指定 入力値1 入力値2 ...
フォーマット(format)を指定して入力された値(文字列や変数)を出力(print)する。
-
フォーマット指定子
は%e
,%f
,%g
,%d
,%s
,%c
などおなじみ。C言語などと同じ。
printf %e'\n' 0.1 #末尾は改行されないので、標準出力の際には改行コードを加える
# 1.000000e-01
# いろいろ出力
printf "%5s %02d; root2 =%.4f, Napier =%g\n" \
"res" 1 \
$(awk 'BEGIN{print sqrt(2)}') \
$(echo "scale=10; e(1)" | bc -l)
# res 01; root2 =1.4142, Napier =2.71828
`コマンド` | printf 書式 `cat`
(コマンドの実行結果をprintfで整形して表示する)
timeコマンド
time 何らかのコマンド
実行時間を計測したいコマンドの前にtimeを置けば、結果を出力してくれる。
参考文献
全般的に
変数について
制御構文について
my備忘録一覧
- Qiitaで使うMarkdown記法 myまとめ (備忘録)
- Bashスクリプトの雑多なまとめ (my備忘録) ← 本記事