ディレクトリ内の一番大きな番号につづくように番号を振ってファイルを作成する
内容
新しくファイルを作るときに、ディレクトリ内のファイル名で一番番号の大きいものの次の番号を持つファイル名で保存する方法。
やり方
保存するディレクトリが変数dir
に入っていて、変数name
に保存するファイル名を入れるようにするとき、以下のように書けば良い。
pattern='s/note_\([0-9]\{2\}\).md/\1/p' if [ ! -e "$dir" ]; then i=1 else i=$(( $(ls "$dir" | sed -n $pattern | tail -n 1) + 1 )) fi name="$(printf note_%02d.md "$i")"
解説
1行目ではディレクトリが存在するかどうかの条件分岐を行い、存在しない場合には番号は1とする。
存在する場合には、ls "$dir"
の結果をsedで見て、pattern
で指定した形になっているものの数字の部分だけを取り出す(ここは自分が連番にしたいファイルの名前で変えればよい)。
tail -n 1
でこの結果の最後だけ取り出し、この結果に1を足す($(( ・ + 1))
)。
最後に、"01"のように、先頭のゼロを含めた形で出力するためにprintfを使っている。
これを適当なスクリプトに組み込めば、作成した順に番号を振りたい系のやつには何でも応用が効く。 (スクリーンショットとか、メモ取る君とか、バージョン管理システムを使うまでもない試行錯誤、ログ取りとか)
蛇足
ここからは自分がどんな風に使っているか、その宣伝みたいななにか。
上の例がそのまま使われたのは、自作のシェルスクリプトtakenoteというやつで、こいつを実行すると今日の日付のディレクトリを作って、その中に連番でmarkdown形式でファイルを作ることができる。 また、オプションをいくつかつけているので、今日の日付のディレクトを、ターミナルで動くファイルマネージャrangerで開いたり、単にその中身をlsで覗いたり、もちろん名前をつけて保存することもできる。
#!/bin/sh # written by Shotaro Fujimoto (https://github.com/ssh0) # first edited: 2015-06-20 takenote() { local get_dir=false local get_name=false local alternative=false local show_list=false local filercmd=ranger local filer=false local rootdir=$HOME/Workspace/blog local pattern='s/note_\([0-9]\{2\}\).md/\1/p' show_usage() { echo "Usage: takenote [-d dir] [-o filename] [-g editor] [-l] [-r] [-h]" echo " -d dir : set the saving directory (default: '$rootdir')" echo " -o filename: set the file's name" echo " -g editor : open with an altenative program (default: '$EDITOR')" echo " -l : list the today's files" echo " -r : open the today's dir or the root dir with the filer (default: '$filercmd')" echo " -h : show this message" } check_dir() { if [ ! -e "$1" ]; then echo "Directory '$1' doesn't exist." return 1 fi } while getopts d:o:g:lrh OPT do case $OPT in "d" ) get_dir=true dir="$OPTARG" ;; "o" ) get_name=true name="$OPTARG" ;; "g" ) alternative=true editor="$OPTARG" ;; "l" ) show_list=true ;; "r" ) filer=true ;; "h" ) show_usage; return 0 ;; * ) show_usage; return 0 ;; esac done # set the saving directory if ! $get_dir; then if check_dir "$rootdir"; then daydir=$(date +%Y-%m-%d) dir=$rootdir/$daydir else return 1 fi fi # only show existing file in the directory if $show_list; then if check_dir "$dir"; then list=$(ls "$dir") echo "$list" fi return 0 fi # move to today's directory by the user defined filer if $filer; then if [ ! -e "$dir" ]; then echo "Today's directory has not been created yet." echo "Open root directory '$rootdir' ..." "$filercmd" "$rootdir" else "$filercmd" "$dir" fi return 0 fi # set the filename if ! $get_name; then if [ ! -e "$dir" ]; then i=1 else i=$(( $(ls "$dir" | sed -n $pattern | tail -n 1) + 1 )) fi name="$(printf note_%02d.md "$i")" fi if $alternative; then $editor "$dir/$name" else $EDITOR "$dir/$name" fi return 0 } takenote $@
zshの補完機能を使うと、さらに便利に使えるようになった。
#------------------------------------------------------------------------------ # takenote completion #------------------------------------------------------------------------------ _takenote() { typeset -A opt_args _arguments -s -S \ "(-l -r -h)-d[set saving directory for specific directory.]: :_files -/" \ "(-l -r -h)-o[set the text file's name.]: :( `takenote -l | sed -n 's/\(.*\.md\)/\1/p'` )" \ "(-l -r -h)-g[open with alternative program (default: vim).]: :(leafpad nano gedit)" \ "(-d -o -g -r -h)-l[only do \`ls dir\`.]: :" \ "(-d -o -g -l -h)-r[cd to TODAY dir, or it doesn't exist, to ROOT dir.]: :" \ "(-d -o -g -l -r)-h[Show the help message.]: :" \ && return 0 } compdef _takenote takenote
それから、これはQiitaに別記事として書いていたのだが、markdown形式で保存し、HTMLファイルに出力することもできる(一度出力すると、次からは保存するごとに自動で更新される)。
また、vim-templateを使っているから、作成したファイルには今日の日付と自分の名前が自動で入り、そしてタイトルの項にカーソルがあった状態でファイルが開かれる。~/.vim/template/template.md
は、以下のように書いてある。
--- title: <+CURSOR+> author: ssh0 date: <%= strftime('%Y-%m-%d') %> ...
まとめ
ということで、後半は単に自分の作った奴の紹介になってしまったが、まぁ、今後自分にとって参考になると思うし、一応残しておこうと思いますよ。