読者です 読者をやめる 読者になる 読者になる

$ service ssh0 start

from everything import *

ディレクトリ内の一番大きな番号につづくように番号を振ってファイルを作成する

内容

新しくファイルを作るときに、ディレクトリ内のファイル名で一番番号の大きいものの次の番号を持つファイル名で保存する方法。

やり方

保存するディレクトリが変数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') %>
...

まとめ

ということで、後半は単に自分の作った奴の紹介になってしまったが、まぁ、今後自分にとって参考になると思うし、一応残しておこうと思いますよ。