🏃‍♂️

今いるディレクトリ下のどこかにあるファイルに一発で移動するシェルスクリプト

に公開

解決したかったこと

プロジェクトのルートにいるときに、例えば main.go とか compose.yml までのパスがパッとわからなくて、なんか cd <Tab> cd <Tab> でファイル一覧見ながら一階層ずつ移動したりすることありません?

もっというと go run ./... したら main.go のあるところにいなくて、いざたどり着いてもう一発 go run ./... したらローカル確認用のコンテナ立ててないのに気づいて compose.yml のところに移動・・・

みたいな、小さなストレス。特にバックエンドもフロントエンドも一つのリポジトリで管理してるようなときによく起こる気がします。

作った

cdf (名前は適当。 cd + find とか file 的な?)のあとに入力した文字列を含むファイル名があるディレクトリに移動してくれる。※今いるディレクトリより下に向かってに限る

ファイルが複数見つかれば、一覧から選択して移動する。(上のGIFでは main.go を検索している例)
1つしか見つからなかったら、一撃でそこに移動する。(上のGIFでは package.json の例)

方法

使うもの

実行する環境で以下のコマンドを使えるようにしておく

書いたシェルスクリプト

適当なディレクトリに以下のようなスクリプトを用意しました。

search_and_cd.sh
#!/bin/zsh

cdf() { #cd + file? find? 的な?
  if [ -z "$1" ]; then
    echo "Usage: cdf <filename>"
    return 1
  fi

  local results
  results=$(fd --hidden --type f "$1" --max-depth 5) #僕は現実的に5くらいで十分と判断

  if [ -z "$results" ]; then 
    echo "No such file."
    return 1
  fi

  local count
  count=$(echo "$results" | grep -c .)

  local target_path=""

  if [ "$count" -eq 1 ]; then 
    target_path="$results" #見つかったファイルが1つだけならpecoに渡さず直接cd
  else
    target_path=$(echo "$results" | peco) #複数ファイルがあればpecoでフィルタリングする
  fi

  if [ -n "$target_path" ]; then
    cd "$(dirname "$target_path")"
  fi
}

# 個人的に使いそうなのをエイリアス登録しておく
# go run ./... や npm run dev できるディレクトリまでのエイリアス
alias cdg='cdf main.go'
alias cdn='cdf package.json'
alias cdc='cdf compose.yml'

シェルの起動時に上記ファイル置き場を読み込む

.zshrc
local scripts_dir="${PATH_TO_SCRIPTS}" #例えば、 $HOME/my_scripts
if [ -d "$scripts_dir" ] && [ -n "$(fd .sh "$scripts_dir" -e sh --maxdepth 1)" ]; then
  for file in "$scripts_dir"/*.sh; do
    source "$file"
  done
fi

ちょい足し

今回用意したものは今いるディレクトリより上に戻るのは支援しないので、上に戻る手段は持っておくと便利。
実用上gitリポジトリのディレクトリ以外では使わないでしょうから、 ghqpeco を組み合わせて任意のディレクトリにサクサク移動できるようにしておくと良いです。

以下は、 g を実行するとローカルリポジトリを検索して、そのプロジェクトルートにいけるようにするエイリアス
(細かい ghq のセットアップの話は別な記事にお任せします。この話だけでいえばざっくり、git config --global ghq.root '~/${リポジトリ置き場}' を事前にしておくとよさめ)

.zshrc
alias g='cd $(ghq root)/$(ghq list | peco)'

実用例

  • cdf package.json して、~/github.com/nodeのなんたら置き場/a_app/package.json 的なとこに移動
  • プロジェクトルートに戻りたくなる
  • g > pecoの画面で node 検索して「nodeのなんたら置き場」を選んでReturn
  • ~/github.com/nodeのなんたら置き場/ に移動成功

おわりに

なんか他にもっとシンプルなやり方がある気がしたけど、なんとなくシェルスクリプトを書きたい気分だったので作ってみた。
うまいことやれば fd と peco と何かしらをパイプでつなぐだけで完成するのかもしれない・・・

最近この手のものはほとんどAIに書かせてたので、久々にパズルを解いて楽しかった。
なんか、正直作って動いて満足しちゃったので本当に使うかはわかんない

Discussion