2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ls実行結果の最後を次のコマンドの引数として使うzshエイリアス

Posted at

何をしたいか

特にログローテーションされている時によくやるコマンド。

$ ls -latr
-rw-r--r--   1 root apache    311 12月  4 05:20 2013 suexec.log-20131205
-rw-r--r--   1 root apache    232 12月 26 17:12 2013 suexec.log-20131227
(中略)
-rw-r--r--   1 root root      573  2月  3 05:32 2014 ssl_error_log
-rw-r--r--   1 root root     4227  2月  3 19:34 2014 error_log
-rw-r--r--   1 root root     7120  2月  3 19:34 2014 access_log
$ less access_log

とか、

$ ls -1
app.log-20140101.gz
app.log-20140102.gz
app.log-20140103.gz
(中略)
app.log-20140104.gz
app.log-20140105.gz
app.log-20140106.gz
$ zcat app.log-20140106.gz

何かとlsの結果の 最後の部分を次のコマンドの引数 にすることが多い。
しかし特に後者の様な場合、入力補完があっても入力がめんどくさい。
そこで楽に入力するためのzshグローバルエイリアスを書いてみた。


設定1 シンプルなカレントディレクトリの最新

~/.zshrcにでも追加。

alias -g new1='${${(@f)"$(command ls -t)"}[1]}'

この場合、
$ cat new1とかすれば、 new1の部分がカレントディレクトリの最新ファイル/ディレクトリに置き換わる。


設定2 少しだけ汎用的にしたバージョン

設定1では、

  • 先頭が「.」のファイル/ディレクトリが取れない。
  • リストターゲットを絞れない。

そこで、もうちょっと改良。

  • 前回のls又はllコマンドと 同じ引数でlsを実行し、その最後の出力 に置き換える。
  • lsのオプションは、-a、-d、-c、-t、-rが前回実行時にあれば、それを引き継ぐ。
  • 実行結果から...は除く。

こうすると、 『直前に実行したlsの最後の出力』 をそのまま次のコマンドに置き換えられる。
以下同様に~/.zshrcにでも追記。

alias -g lsl1='$(__get_last_lsret)'
function __get_last_lsret(){
  local LSCMD CMD_PARTS RERUN CMD_ARGS RERUN_ARGS RES_LIST RES_LIST_L1
  for LSCMD in ${(@f)"$(fc -lnr -m "l[sl]*")"}
  do
    : ${(A)CMD_PARTS::=${(z)LSCMD}}
    if [[ ${CMD_PARTS[1]} == "ls" || ${CMD_PARTS[1]} == "ll" ]];then
      RERUN="command ls -1"
      shift CMD_PARTS
      for CMD_ARGS in ${CMD_PARTS[*]}
      do
        if [[ ${CMD_ARGS} == "-"* ]];then
          for OPT in c d t r a
          do
            if [[ ${CMD_ARGS} == *${OPT}* ]];then
              RERUN="${RERUN} -${OPT}"
            fi
          done
        else
          RERUN_ARGS="${RERUN_ARGS} ${CMD_ARGS}"
        fi
      done
      break
    fi
  done

  if [[ -n ${RERUN_ARGS-} ]];then
    RERUN="${RERUN} ${RERUN_ARGS}"
  fi
  RERUN="${RERUN} | grep -Ev '^(\.|\.\.)$'"
  : ${(A)RES_LIST::=${(@f)"$(zsh -l -c ${RERUN})"}}
  : ${(A)RES_LIST_L1::=${(z)${RES_LIST[${#RES_LIST[*]}]}}}
  echo ${RES_LIST_L1[${#RES_LIST_L1[*]}]}
}

この設定では、lsl1が前回ls実行時の最後の出力に置き換わる。

$ ll access_log*
-rw-r--r-- 1 root root   7120  2月  3 19:34 2014 access_log
-rw-r--r-- 1 root root  42989  1月 12 02:37 2014 access_log-20140112
-rw-r--r-- 1 root root 122341  1月 19 03:31 2014 access_log-20140119
-rw-r--r-- 1 root root  98802  1月 26 01:32 2014 access_log-20140126
-rw-r--r-- 1 root root  60190  2月  2 01:32 2014 access_log-20140202
$ less lsl1
(access_log-20140202が開かれる)

とか

$ ls -1tr
app.log-20140101
app.log-20140102
app.log-20140103
(中略)
app.log-20140104
app.log-20140105
app.log-20140106
$ vim -R lsl1
(app.log-20140106が開かれる)

あるいは日付がディレクトリになっているようなケースで

$ ls -1d 2014-01-*
2014-01-02/
2014-01-03/
2014-01-04/
2014-01-05/
$ cd lsl1
(2014-01-05に移動)

といったことが可能である。

出来ないこと

  • 直前にカレントディレクトリ以外をlsしていると失敗する。
  • ls -Rとかされると崩れる。
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?