1
1

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.

コマンド履歴 - 覆水を盆に返す

Last updated at Posted at 2015-03-14

なんかで、mv したのを元に戻したいとき
なんかで、cp したのを元に戻したいとき

コマンドを懇切丁寧に打ち直すのは避けたいものだ。
そんな時は、コマンド履歴。つっても、 history やら fc やらのお話では無い。(関係はしてるけど)

キーワードは、 bash の「イベント指示子」と「単語指示子」とその「修飾子」。
もちろん、 zsh でも使える。

ファイル対ファイル

前提
  • コマンドに対するオプションを使ってない、ファイル対ファイルの単純なケースを想定
  • 対象コマンドでは、ブレース展開を使ってない(履歴に残ってない)事。
    • ブレース展開を使ってた場合については後述
$ touch foo
$ mv foo foo.bak

なんらかの理由で .bak を元に戻したい時

直近

対象 mv 以降にコマンドを打っていないケースの場合。

mv に直近のコマンドの最後の引数 !$ と二番目のコマンド文字列 !:1 を与える。

$ mv !$ !:1

第一引数 !^ を与える。

$ mv !$ !^

もしくは、多くのケースでは、

mv に直近のコマンドの最後の引数 !$ と、それの拡張子を除いた単語 !$:r を与える。

$ mv !$ !$:r

拡張子ではなく、foo~ の様にしていた場合は、

$ mv foo foo~
$ mv !$ !$:s/~//
  • 早合点しがちだが、 s/// の変換前部分も 正規表現表記ではない。単なる文字列。(変換後部分は言うまでもないが)

実際に使うのは

殆どの場合は、別の作業をした後に実行するので、

コマンド履歴の番号でアクセスするか、コマンド文字列参照によってアクセスする事になる。

コマンド履歴の番号
$ history
(略)
140 mv foo foo.bak
(略)
$ mv !140$ !140:1
直近からの番号
$ mv !-2$ !-2:1

2回前だった場合ね

コマンド文字列参照
$ mv !m:$ !m:1

more とか他の m で始まるコマンドを間に挟んでたら、!m!mv にすればいい。

  • 文字列の時は、 !m$ はエラーになる。同様に !m^ も。

ブレース展開を使ってた場合

$ mv foo{,.bak}

展開してない状態で履歴に残ってたら。

直前なら、

^,.bak^.bak,

そうでないなら、

!mv:s/.bak,/,.bak/
  • こちらも、 s/// の変換前部分は 正規表現表記ではない。単なる文字列。
    大事な事なので二度言いました。
  • このケース。 zsh では、 文字列記載後にタブを打つ事で、展開させる事が可能なので、展開させて制約を除くほうが都合が良い。

ここまで押えれば、

後は、ケースバイケース。工夫次第で、色々活用出来る。

例えば、ある拡張子を持つファイルを、ごそっと移動した以下の様な場合に、元に戻したくなったとする。

$ touch foo.pl bar.pl buz
$ mkdir foo
$ mv *.pl foo

移動先に同一拡張子のものが無いと言う保証があるなら、

$ mv !$/!:1 .

で復元が出来る。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?