日々発生するの技術ネタ、アイデアはMarkDown書式で適当に追加しておます。重要なのは全てにおいて**「スピード」**です。
僕のライフスタイル的にMarkDownファイルの作成頻度がメチャ高いのです。
ファイル名を手入力するのが面倒くさい
MarkDownファイルを作成するたびにファイル名を手動で付けていたのですが、以下の課題が顕著に現れてきました。
- 命名におけるケアレスミスの発生
- ファイル名をつけるだけで、ちりつもで時間がかかる
という事で任意のディレクトリ内のファイル名を元に連番ファイルを作成するシェルスクリプトを作って自動化してみたいと思います。
今回作りたいファイルのフォーマットはコチラです。
「年月日連番(3桁)-任意の文字列」
自動化するのは**「年月日連番(3桁)」**部分です。
要件
- 日付はローカル日時
- 既に同名が存在すれば連番をインクリメント
- 連番は3桁固定で3桁満たない場合は0で埋める
日付はローカル日時
date=`date '+%Y%m%d'`
# 出力例 : 20200922
date関数を使って日付文字列を作成します。個人的にフォーマット先頭の+
を忘れやすいです。
指定のディレクトリ内のファイル名リストを作成
今回の検索対象はdrafts/
ディレクトリ内且つMarkDownファイルのみです。
# draftsディレクトリ内を検索
dir='drafts/'
# 検索対象
target="$dir*.md"
# find関数で検索ファイルパスのリストを作成
files=`find $target -type f -maxdepth 0 -name $date*`
find関数を使って、指定した検索対象のファイルパスのリストを取得します。
find関数の補足説明
-type f
-type
オプションでファイルを検索対象としています。(フォルダは対象外)
-maxdepth 0
-maxdepth 0
オプションでサブフォルダは検索対象外としています。
-name $date*
-name
オプションでファイル名のルールを加えて絞り込みます。
これでfiles変数に指定した日付のMarkDownファイルパスのリストが格納されました。
連番の作成
例 : drafts/20200922004-hogehoge
この「004」の部分。文字列15番目から3つの文字列を抽出します。
# 作成済み連番の最大値
max_serial=0
for filepath in $files;
do
# 連番情報を抽出する
serial_num_str=`echo ${filepath:15:3}`
# 文字列を数字にキャスト
serial_num=$(expr $serial_num_str)
# 連番の最大値を保持
if [ $max_serial -lt $serial_num ];then
max_serial=$serial_num
fi
done
ファイル名の連番を抽出して、最大値を取得します。
文字列を数値にキャストして比較
文字列のままだと数値の比較はできないので、数値にキャストします。
serial_num=$(expr $serial_num_str)
この部分で文字列(例:012)を数値(12)にキャストしています。
if [ $max_serial -lt $serial_num ];then
-lt
を使って比較しています。 if [ A -lt B ]
AがBより小さかったらmax_serialを更新します。
連番をインクリメントしてファイル生成
new_id=$(expr $max_serial + 1)
先程のキャスト処理を使って使用する連番を決定します。
3桁に0埋めする
new_num=`printf %03d $new_id`
printf関数に引数でフォーマット(%03d
)を指定して必要があれば0で埋めます。
例:12 -> 012
最後に
以下のgifアニメでは分かり辛いですが、シェルを実行するたびに連番ファイルが作成されるようになりました。
これで技術メモする時のMarkDown作成のストレスが減りそうです。
全ソースはコチラにアップしています。