【Mac】ターミナルでプログレスバー

ターミナルでカウントダウン、という話で、 echo -e "\r" を使えば、同じ行に留まって数字の移り変わりを表示できることがわかった。
 これを利用すれば、Homebrew とかでよく見る、あこがれのプログレスバーが実現できそうだ。

さっそくやってみる

📝 prog.sh
#!/bin/bash

jikan=0
bar=''

while [ $jikan -lt 20 ]
do
	echo -en "$bar\r"
	sleep 1
	jikan=`echo $((jikan + 1))`
	bar="$bar"'#'
done
echo $bar

#!/bin/bash でないと動かないので注意が必要だ。
 一秒にひとつずつ bar という変数に「#」を追加していく。それをキャリッジリターンで同じところに表示すれば、それっぽく見えるはずだ。

うまいこと動いてくれた。

一秒ごとにプログレスバーが動いてもあまり面白くない。
 プログレスバーが意味を成すのは、何パーセント処理が進んだか、を示すときだろう。バーを表示する関数をつくって、そこに百分率の数字を引数として投入する、という使い方がいいのではないかと思った。
 上記のシェルスクリプトを書き直してみる。

プログレスバーを関数にする

#!/bin/bash

jikan=0

function prog() {
	suji=`echo ${1%.*}`
	sinko=`echo $((suji / 5))`
	if ! test $sinko -eq 0; then
		bar=''
		for INT in `seq $sinko`
		do
			bar=$bar'#'
		done
		echo -en " $bar $suji%\r"
	fi
}

while [ $jikan -le 20 ]
do
	Count=`echo "scale=1; $jikan * 100 / 20" | bc`
	prog $Count
	sleep 1
	jikan=`echo $((jikan + 1))`
done
echo $bar

suji=`echo ${1%.*}` というのは、よく拡張子を削除するのに使われる変数展開だ。ここでは小数点以下を切り捨てるのに使っている。
 百分率の数字を 20 個の「 # 」で表すことを想定して、 echo $((suji / 5)) で 5 % ごとに # を増やす。
scale=1; $jikan * 100 / 20" | bc というのは、少数の計算だ。scale=1 の数字を増やして桁数を上げていくと、より正確な百分率を出せる。少数の計算については、下記の記事を参考にさせていただきました。

🔗 シェルbash で小数の計算するコマンド – それマグで!

これをふまえて、【Mac】Platypus で遊ぶ – ProgressBar | 林檎コンピュータ
で使ったシェルスクリプトに、上記の関数を埋めこんでみたいと思う。

dl.sh に使用してみる

あまり出来がよくないが、サムネイル画像のリンク先の画像を取得するスクリプトだ。 dl.sh 記事URL というふうに使う。

📝 dl.sh
#!/bin/bash

# プログレスバーの関数
function prog() {
	suji=${1%.*}
	sinko=`echo $((suji / 5))`
	if ! test $sinko -eq 0; then
		bar=''
		for INT in `seq $sinko`
		do
			bar=$bar'#'
		done
		echo -en " $bar $suji%\r"
	fi
}

# 作業フォルダを設定
saveLoc=~/Desktop
cd $saveLoc

if ! test -e ./dlTmp; then
	mkdir ./dlTmp
else
    rm -rf ./dlTmp
    mkdir ./dlTmp
fi
cd ./dlTmp

# 記事をダウンロード
url="${1}"
wget --quiet "${url}"
nkf -w * >utf.txt

# 記事のタイトルを取得
blogtitle=`cat utf.txt | tr -d '\n' | grep -o "<title>[^<]*</title>" | sed -e 's/<[^>]*>//g' -e 's/^ *//'`

echo $blogtitle

# 画像リンクの取得
grep -oE "<a href=\"[^<]*\"|<a href=[^<]*" utf.txt | tr ' ' '\n' | tr '"' '\n' | tr '=' '\n' | grep -E 'jpg$|jpeg$|png$|gif$' > list.txt

# 画像の枚数を数える
maisu=`wc -l list.txt | sed -e 's/list.txt//' -e 's/ //g'`
num=0

# 画像のダウンロード
for file in `cat list.txt`
do
	wget --quiet $file
	num=`echo "$((num + 1))"`
	per=`echo "scale=1; $num * 100 / $maisu" | bc`
	prog "$per" # プログレスバー
done
echo ' #################### 終了'

# zipファイルにまとめる
zip -0 -q "${blogtitle}".zip *.jpg *.gif *.png *.jpeg
if test $?;then
	cp "${blogtitle}".zip "$saveLoc"/
fi
cd $HOME

ちょっと大雑把な感じだが、プログレスバーは動くので、まぁ良しとする。