シェルのコマンド履歴から再利用、のいろいろ

by Creativity+ Timothy K Hamilton


覚えていると、たまに便利かもしれない"bash"のコマンド履歴の展開に関する技を、例を交えながらまとめてみました。
最後にも書きましたが、他にもたくさんありますので、色々試してみてください。

直前に実行したコマンドを実行

"!!"コマンドで、1つ前に実行したコマンドを再度実行できます。

$ ls -l
合計 0
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:20 test
$ !!
ls -l
合計 0
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:20 test

n個前に実行したコマンドを実行

"!-n"コマンドで、n個前に実行したコマンドを再度実行できます。
例えば、以下の例では、"!-2"とすると、2個前に実行したコマンドを実行しています。

$ ls
test
$ ls -l
合計 0
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:20 test
$ !-2
ls
test

上で紹介した"!!"コマンドは、"!-1"コマンドと同等ということになります。

特定の文字列で始まるコマンドのうち、一番近いコマンドを実行

"!string"で、stringで始まるコマンドのうち、過去に一番最近実行されたものを再度実行します。
以下の例では、"!p"とすることで、pから始まる直近で実行されたコマンド(pwd)を実行しています。

$ pwd
/home/rx7/tmp
$ ls
test
$ !p
pwd
/home/rx7/tmp

特定の文字列を含む過去のコマンドで、一番近いコマンドを実行

1つ上のと、よく似ていますが、
"!?string"では、stringを含むコマンドのうち、過去に一番最近実行されたものを再度実行します。
1つ上との違いは、この場合はコマンドや引数、オプションを区別しない点です。

$ ls -l
合計 0
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:20 test
$ echo ls
ls
$ !?ls
echo ls
ls

履歴から実行されるコマンドの確認

過去に実行されたコマンドの履歴から、再利用する形でコマンドを実行できることは便利ですが、慎重に実行したい場合などは、実行内容を確認したい場合もあるかと思います。
そういったときは、":p"を付けることで、実行されるコマンドが表示される"だけ"で、何のコマンドが実行されるのかを確認することが出来ます。

$ ls -l
合計 0
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:20 test
$ !!:p
ls -l

直前のコマンドの(最後の)引数を再利用

"!$"を使うことで、以下のように直前に実行したコマンドの最後の引数を利用することができます。

$ pwd
/home/rx7/tmp
$ mkdir hoge
$ cd !$
cd hoge
$ pwd
/home/rx7/tmp/hoge

直前のコマンドの全ての引数を再利用

"!*"を使うことで、以下のように直前に実行したコマンドの全ての引数を利用することができます。

$ touch foo bar
$ ls -l !*
ls -l foo bar
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:25 bar
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:25 foo

文字列の一部を変更して実行

"^before^after"の形式で実行することで、直前のコマンドの特定の文字列を置換して実行することができます。
例えば、以下の例では、直前のコマンドの(引数である)"hoge"を"fuga"に置換して実行を行っています。

$ ls -l
合計 0
$ touch hoge
$ ^hoge^fuga
touch fuga
$ ls -l
合計 0
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:28 fuga
-rw-rw-r-- 1 rx7 rx7 0 2009-02-26 02:28 hoge


これは、"!!:s/hoge/fuga/"でも代替可能です。
つまり応用すると、直前のコマンド以外でも置換して実行できます。

その他、参考

http://www.linux.or.jp/JM/html/GNU_bash/man1/bash.1.html」がリファレンスとなっており、とても参考になります。
以下に、今回の話題に関連する一部分(履歴の展開)を転載させていただきます。

イベント指示子 (Event Designator)

イベント指示子は、履歴リスト中のコマンドラインエントリを参照するものです。

!
    履歴置換を開始します。ただし、ブランク文字、改行文字、=, ( のいずれかが後に続く場合は除きます。 
!n
    n 行目のコマンドラインを参照します。
!-n
    現在から n 行前のコマンドラインを参照します。
!!
    1 行前のコマンドラインを参照します。`!-1' と同義です。
!string
    string で始まるコマンドのうち、一番現在に近いところで実行したものを参照します。
!?string[?]
    string を含むコマンドのうち、一番現在に近いところで実行したものを参照します。 string の直後が改行文字ならば、最後の ? は省略しても構いません。
^string1^string2^
    簡易置換。 string1 を string2 に置換して直前のコマンドを繰り返します。 ``!!:s/string1/string2/'' と同義です (後述の修飾子を参照)。
!#
    今までのところまでに打ち込んだコマンドライン全体です。

単語指示子 (Word Designators)

単語指示子 (word designator) は、イベントから欲しい単語を選ぶ時に用いられます。イベント指定と単語指示子のセパレータには : を用います。単語指示子が ^, $, *, -, % のいずれかで始まる場合には、このセパレータは省略できます。単語には行の先頭から番号が振られます。先頭の単語が 0 番目になります。単語は現在の行に、空白 1 つで区切られて挿入されます。

0 (ゼロ)
    0 番目の単語。このシェルにとっては、これはコマンドを表す単語です。
n
    n 番目の単語。
^
    最初の引き数。つまり 1 番目の単語です。
$
    最後の引き数。
%
    `?string?' 検索にマッチする、一番現在に近い単語。
x-y
    単語の範囲。`0-y' の省略形として `-y' が使えます。
*
    0 番目を除く全ての単語。これは `1-$' の別表現です。イベント中に 1 つしか単語が現われないときに * を使ってもエラーにはなりません。このような場合には空文字列が返されます。
x*
    x-$ の省略形です。
x-
    x* と同様に x-$ の省略形ですが、ただし最後の単語は含みません。

イベント指定なしに単語指示子が与えられた場合、直前のコマンドがイベントとして使われます。

修飾子 (Modifiers)

単語指示子 (省略可能) の後には、以下に示す修飾子を、1 個以上のシーケンスのかたちで置けます。それぞれの修飾子の前には `:' をつけます。

h
    パス名から末尾にある部分 (ファイル名) を取り除き、前の方 (ディレクトリ部) だけを残します。
t
    パス名から前の方 (ディレクトリ部) を取り除き、末尾にある部分 (ファイル名) だけを残します。
r
    末尾にある .xxx 形式のサフィックスを取り除き、ベース名 (basename) だけを残します。
e
    末尾のサフィックスだけを残して、全ての部分を取り除きます。
p
    新しいコマンドを表示しますが、実行はしません。
q
    置換が行われた単語をクォートし、それ以上の置換が行われないようにします。
x
    q と同じように置換後の単語をクォートしますが、 空白文字 と改行文字のところで単語に分割します。
s/old/new/
    イベント行で最初に現われた old を new に置き換えます。/ の代わりに任意の区切り文字を使うこともできます。最後の区切り文字がイベント行の最後の文字ならば、これは省略できます。 old と new の中では、バックスラッシュ 1 つでクォートすれば区切り文字も使えます。 new に & が含まれている場合には、これは old に置き換えられます。バックスラッシュ 1 つを前に置けば & をクォートできます。 old が空文字列ならば、これには前回に置換された old が設定されます。以前に履歴置換が全く行われていない場合には、現在に一番近い !?string[?] の検索で使われた string が設定されます。
&
    直前の置換を繰り返します。
g
    変更をイベント行全体に適用します。これは `:s' と組み合わせて使われます (例:`:gs/old/new/')。 `:s' と一緒に使った場合には、 / の代わりに任意の区切り文字を使えます。また最後の区切り文字がイベント行の最後の文字ならば、これは省略できます。


UNIXシェルスクリプトコマンドブック

UNIXシェルスクリプトコマンドブック