bashシェルスクリプト入門3

筆者がよく使うシェルスクリプトをまとめました。

ファイル数を調べる

lsコマンドとwcコマンドを使って、カレントディレクトリの*.png の個数を調べます。wc --lineは行数を表示します。

wcって何?

word countが名前の由来ね。
バイト数、単語数、行数を表示するコマンドよ

$ ls *.png | wc --line 13 $ png_cnt=$(ls *.png | wc --line) $ echo $png_cnt 13

ただし、*.pngが0個の場合、stderrに「ls: '*.png' にアクセスできません: そのようなファイルやディレクトリはありません」と表示されてしまいます。

$ ls *.png | wc --line ls: '*.png' にアクセスできません: そのようなファイルやディレクトリはありません 0 $ png_cnt=$(ls *.png | wc --line) ls: '*.png' にアクセスできません: そのようなファイルやディレクトリはありません $ echo $png_cnt 0

エラーみたいで、気になるわ

pngファイルが1個もない。

「*.png」をシェル展開できない。

「*.png」というファイルを探した。

そのようなファイルはない。

さいわい、png_cntには0が設定されて、結果は期待どおりです。

このメッセージが気になる場合は、findコマンドを使います。「-maxdepth 1」を指定すろと、カレントディレクトリだけを探し、サブディレクトリ下を検索しません。

$ find . -name "*.png" -maxdepth 1 | wc --line 13 $ png_cnt=$(find . -name "*.png" -maxdepth 1 | wc --line) $ echo $png_cnt 13

「-maxdepth 1」を指定しなければ、サブディレクトリを含めて、*.png の個数を調べます。

$ find . -name "*.png" | wc --line 13 $ png_cnt=$(find . -name "*.png" | wc --line) $ echo $png_cnt 13

ファイルサイズを調べる

ファイルサイズが 0より大きいかを調べるには、ファイルテスト演算子 -s を使います。ファイルが存在しない場合は、ファイルサイズ=0として判断されます。

#!/bin/bash -ue if [ -s "myfile.txt" ]; then echo "filesize > 0" else echo "filesize = 0" fi

ファイルが存在することを確認したい場合は、ファイルテスト演算子 -f を使います。

#!/bin/bash -ue if [ -f "myfile.txt" ]; then echo "file exists" else echo "file not exists" fi

ファイルサイズ=0で、ファイルが存在することを確認したい場合は、-f と -s を組み合わせて使います。

#!/bin/bash -ue file="myfile.txt" if [ ! -f $file ]; then echo "file not exists" else if [ -s "myfile.txt" ]; then echo "filesize > 0" else echo "filesize = 0" fi fi

else if って書けないの?

書いてもいいけど、期待している else if とは違うと思うわ。

ファイルサイズ1000以上かどうかって調べられるのかな?

statコマンドの"-c %s"オプションで、ファイルサイズを調べます。

file statusを表示するので、statコマンドね。

ファイルが存在しないとき、size=""(空白)となり、続く、if文の比較でエラーになってしまいます。そこで、size=${size:-0}で、sizeが空白なら0、とするようにしています。

-ge は、数値比較の >= の意味です。

#!/bin/bash -ue file="myfile.txt" size=$(stat -c %s $file) size=${size:-0} if [ $size -ge 1000 ]; then echo "size >= 1000" else echo "size < 1000" fi

wc --bytes でもファイルサイズがわかるね

んー、たしかにそうだけど、
statコマンドのほうが速いから、
wc --bytesを使う場面はあまりないわね

npmのpackage.jsonのversionをインクリメントする

Jenkinsでdevelopブランチから引っぱってきて、各種テストに合格したら、versionをインクリメントして、masterブランチにコミットしてpush、という場面です。

ここでは、npmの設定ファイルpackage.jsonのversionの末尾をインクリメントします。次のような場合は、「19」を「20」にします。

{ "name": "jquery-jpostal-ja", "version": "2.13.19",

"2.13"の部分は、手作業で編集してgit commitするんだね。

シェルスクリプトとsedで処理します。

JSONフォーマットだから、nodejsで処理したほうが自然かもね

npm_increment_version.sh

#!/bin/bash -ue # package.jsonのversion項目、先頭にスペース2個あり # # "version": "2.13.19", #↓ # "version": "2.13.20", # # cur_ver: 19 # new_ver: 20 # message: 2.13.20 cur_ver=$(cat package.json | grep -e "^ \"version" | sed -r "s/^( \"version\": \"[0-9]+\.[0-9]+\.)([0-9]+)(\",)/\2/") echo "cur_ver:" $cur_ver new_ver=$((cur_ver + 1)) echo "new_ver:" $new_ver cat package.json | sed -r "s/^( \"version\": \"[0-9]+\.[0-9]+\.)([0-9]+)(\",)/\1$new_ver\3/" >tmp.json cp tmp.json package.json rm tmp.json message=$(cat package.json | grep -e "^ \"version" | sed -r "s/^( \"version\": \")([0-9]+\.[0-9]+\.[0-9]+)(\",)/\2/") echo "message:" $message
$ ./npm_increment_version.sh cur_ver: 19 new_ver: 20 message: 2.13.20

正規表現って他の人にはわからないよね

書いた本人だって、すぐには思い出せないわよ

タイトルとURLをコピーしました