殿堂入り記事

[小ネタ] mkdir したディレクトリに cd する方法 9 選 +1 (BASH) ※追記あり

2017.09.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

$ mkdir /very/_very/Very-long/directory_name/20170915

なんて操作をしたあと、そのディレクトリにcdしたい場合ってまれによくありますよね。

どんなやり方があるか考えてみました。

1. コピペする

そのまんまですが、これをやりたくなくてこの blog を書いてます。

2. TAB 補完で頑張る

これも無いわけではないですが、間違えたりすることを考えると正直あんまりやりたくないです。

3. 上矢印キーで前コマンドを呼び出し、右矢印キーで先頭に戻ってmkdircdに書き直す

よく見る方法ですが、もうすこし少ない手数でできないでしょうか。

4. 上矢印キーで前コマンドを呼び出し、Ctrl-Aで先頭に戻ってCtrl-Dx5 のあとにcd

BASH のキーバインドはデフォルトだと emacs モードなので、このやり方が出来ます。

でもまだちょっと手数が多いですね…

5. 上矢印キーで前コマンドを呼び出し、Ctrl-AAlt-FCtrl-Wcd

BASHのコマンドラインは、Alt+F/Bでワード(単語)ごとに移動できます。

Ctrl-Wはワード単位での削除になりますので、これを使うとちょっとだけ手数が稼げました。

6. 上矢印キーで前コマンドを呼び出し、Ctrl-WCtrl-Ccd + Ctrl-Y

Ctrl-W は上でも使いましたが、実はこの削除した内容は、あとから貼り付けることが可能です。

  • Ctrl-W でパス部分を削除し、
  • Ctrl-C でいったん行をクリア(かわりに下矢印でも可)、
  • cd(半角スペース) と入力したあと、
  • Ctrl-Y で、上で削除した内容をペーストする

Ctrl-WCtrl-Yは、覚えておくととても便利なのでお勧めです。

ただやっぱり手数が多いのと、
あと、そろそろ「上矢印キー」から離れたいところ。

もう少し、例えば手順書からコピペ実行するような際にも使える方法はないでしょうか。

7. 作成するディレクトリ名をあらかじめ変数に入れておいて(以下略)

$ DIR=/very/_very/Very-long/directory_name/20170915
$ mkdir $DIR
$ cd $DIR

こんなやつですよね。シェルスクリプトならよく使う手かと思います。

手順書からのコピペだけを念頭に置けば悪くない手ですが、mkdir する前に変数にいれておかないとならないので、 場合によっては冗長ですし、 手作業での操作中にはなかなか使いづらい感じがあります。

 


 

要は、mkdir したときに指定した引数をあとから参照できればよいのですが、
そんな方法はないでしょうか。

もちろん、あります。

8. cd $_

このあたりから本命です。

$ mkdir /very/_very/Very-long/directory_name/20170915
$ cd $_
$ pwd
/very/_very/Very-long/directory_name/20170915
$

BASHの $_ という特殊変数を使うことで、「ひとつ前に実行したコマンドラインの最後の引数」を参照することができます。これを cd の引数に渡してあげればよいわけです。

マニュアル知識で申し訳ないですが、この変数は zsh にもあるそうです。ご参考まで。

9. cd !!$

こちらも似たような感じで使えますが、挙動と動作の仕組みがちょっとだけ違います。

$ mkdir /very/_very/Very-long/directory_name/20170915
$ cd !!$
cd /very/_very/Very-long/directory_name/20170915
$

!!というのは、ひとつ前に実行したコマンドラインを再度引用して実行しなさい、という BASH コマンドです。
この直後に$をつけることで、そのコマンドラインの最後の引数のみを取り出す、という動作になります。

cd 実行時、ちゃんと引用が展開されたコマンドラインが表示されるので、確認する手間がちょっと省けた感じでいいですね。

こちらのやり方も、zsh で一応動きました。

ただしこちらはヒストリの状況に動作が左右されかねないため、
シェルスクリプトとして使う場合には 7. か 8. の方法あたりが無難かも知れません。

おまけ cd !$

!!$のかわりに!$でも可能です。

本来 !$ のあいだには何か文字(イベント指示子)が必要になるのですが、

$(ワード指示子)の前にイベント指示子が省略された場合は、直前に実行されたコマンドラインを参照する」

という暗黙の動作があるからです。

細かい挙動は、BASH の manpage HISTORY EXPANSIONの章をご参照下さい。


 

以下、頂いたコメントからいくつか拾わせていただきます。コメントして下さった方々ありがとうございました。

追記 1. cdESCキー → .あるいは_

すいません知りませんでした。。。

BASH の manpage から引用すると、insert-last-argument というコマンドとのことです。

ちなみに Alt-.Alt-_ というキーバインドも使えるはずなのですが、Mac で iTerm2 を使われていると、デフォルトでは動かない(別の文字が入力される)と思います。

使いたい場合は、 iTerms2 の Preferences を開き、Profiles の Keys 設定のところで option (alt) キーの動作を「+Esc」に変更して下さい。

appendix-1

追記 2. viモードでESCk 0 cw cd

上で「BASHのキーバインドは emacs だ」と言いましたが、ということはつまり vi キーバインドにも変更できるということです。例えば

$ set -o vi

と実行すると、BASH で vi のキーバインドが使えます。vim ではないですよ、vi です。

通信回線の帯域が数百bps、ギガどころかキロですらない単位の頃に開発された vi エディタは、如何に少ないキーストロークで最大の編集効果をあげるか、という設計方針で作られているように思います。
そんな vi と同じ操作で BASH が使えるのですから、効率がよいのも頷けます。

ちなみにキー操作の意味は、下記になります。

  • ESCキーで編集モードに
  • kで前回実行のコマンドラインを呼び出し(≒上矢印キー)
  • 0(ゼロ)で行の先頭に。既に先頭にカーソルがあるかもですが念のため
  • cw「change-word」コマンドの実行、続いて、
  • cdと打つことで、mkdircdに置き換えられました

あとはエンターキーで実行です。

追記 3. mkdir と cd を同時に実行する関数をあらかじめ定義しておく

例えば.bash_profileに下記のように書いておいて、というパターンかと思います。

mkdir-cd(){
  mkdir $1 && cd $1 && pwd
}

コメントを見ると、関数名はmkcdとされる方が多いようですね。

あらかじめ定義しておかないと使えないし、うっかりmkdirで実行してしまうと意味が無いので、個人的には今回のケースでは。。。なのですが、でも「BASH関数で解決する」という方法は応用が利きますし、なにより各々方がそれぞれやりやすいやり方でやるのが一番ですよね。

 


 

そのほか !!:s/mkdir/cd/ というやり方もあるかと思いますが、今回の場合だとキーストローク的にあんまりうれしくはないかも知れません。

総評

慣れの問題も大きいのですが、個人的には下記のような感じで方法を使い分けてます。

  • ターミナルでの手作業 -> 6.
  • ちょっと気取った手順書を作りたいとき -> 8.
  • シェルスクリプト -> 7.
  • ターミナル作業で、ちょっと複雑なコマンド修正が必要なとき -> 4. 〜 6.
  • いうほど長いパスじゃないとき -> 6. か 2.
  • キーボードに手を伸ばすのが面倒なとき -> 1.

正直 8. と、その下調べの最中に見つけた 9. の方法を書きたいがための記事ですが、
BASH にも便利に使えるショートカットがいろいろあることも併せてお伝えしたかったので、結果こんなポエムっぽい記事になりました。

どこか一部でも、読まれた方のお役に立つ内容がありましたら幸いです。