前置き
以前こんな記事を書きました
→【bash】!-n$
ができるってそれもっと早く教えてよ! - Qiita
bash(以外でもあると思いますけど)のヒストリ機能では、
!-3
で3回前のコマンド実行、!$
で直前のコマンド実行の最後の引数、!-2$
で2回前のコマンド実行の最後の引数、などが参照できます。
その辺りを調べるために、man bash
のHISTORY EXPANSION
(履歴の展開)セクションを読んでいたらこんなものもありました。
!# The entire command line typed so far.
日本語版(Man page of BASH)
!# これまでに打ち込んだコマンドライン全体。
つまり以下のような動きをします
$ echo hoge fuga !#
echo hoge fuga echo hoge fuga
hoge fuga echo hoge fuga
?????
一旦なにに使えるんだ??
と最初に読んだときは思いました。
が、最近使いどころがわかってきたので紹介します
本題
「!# これまでに打ち込んだコマンドライン全体。
」というのは、見方を変えると、
!!
が!-1
のエイリアスだとすると、!#
は!-0
のエイリアスだと見ることができます。
(実際には!-0
なんて使えないですけど。)
つまり、!#
もイベント指示子なので、単語指示子と組み合わせて使えばいいのです
(これに最初気付かなかった )
例えば、!#$
という風に$
を付けると、「直前の引数」を参照できます。
つまり、
cp path/to/file !#$.bak
で
cp path/to/file path/to/file.bak
になります
(ちなみにこれならcp path/to/file{,.bak}
でもできますが)
また、
mv path/to/typo !#$:s/po/pe
で
mv path/to/typo path/to/type
になります
ちょっと使いどころが見えてきましたね?
しかも、!!
や!$
などと違って、「それまでに実行したコマンド」の影響を受けないので、
むしろそれらより気軽に手順書とかに使えますね。
例えば、たくさんの設定ファイルを所定の場所に配置する、と言った場合、普通に書くと以下のようになります。
※サーバー上に配置するファイルを、どこか(ホームディレクトリとか)のdeploy_files
ディレクトリ下に、ディレクトリ構造を保った状態で一旦配置して、そこからコピーする場合を想定
cp deploy_files/pathA/to/fileA /pathA/to/fileA
cp deploy_files/pathB/to/fileB /pathB/to/fileB
cp deploy_files/pathC/to/fileC /pathC/to/fileC
別にコピペで済むんですけど、いちいち2箇所書き換えるのが面倒です。
これが、!#
を使うとこう書けます。
cp deploy_files/pathA/to/fileA !#$:s/deploy_files/
cp deploy_files/pathB/to/fileB !#$:s/deploy_files/
cp deploy_files/pathC/to/fileC !#$:s/deploy_files/
書き換えるのが一箇所で済むようになりました
それでは良きCLIライフを