今いるディレクトリ下のどこかにあるファイルに一発で移動するシェルスクリプト
解決したかったこと
プロジェクトのルートにいるときに、例えば 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 の例)
方法
使うもの
実行する環境で以下のコマンドを使えるようにしておく
-
fd
: 検索用 -
peco
: フィルタリング用 - (Optional)
ghq
: リポジトリ管理用
書いたシェルスクリプト
適当なディレクトリに以下のようなスクリプトを用意しました。
#!/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'
シェルの起動時に上記ファイル置き場を読み込む
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リポジトリのディレクトリ以外では使わないでしょうから、 ghq
と peco
を組み合わせて任意のディレクトリにサクサク移動できるようにしておくと良いです。
以下は、 g
を実行するとローカルリポジトリを検索して、そのプロジェクトルートにいけるようにするエイリアス
(細かい ghq のセットアップの話は別な記事にお任せします。この話だけでいえばざっくり、git config --global ghq.root '~/${リポジトリ置き場}'
を事前にしておくとよさめ)
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