ShellScript

よく使うワンライナー


これはなに?

私がよく利用するワンライナー。

でもなんでもワンライナーで済ませたくなるワンライナー病には気をつけたい。ワンライナーは脳みそをあまり使わないで手軽に使えることが重要なので、ワンライナーを作ることに情熱を注ぐべきではない。


git関連


検索キーワードが含まれるファイル名だけを返す

$ git grep -l hoge | xargs grep -l foo

git grep -l hogehogeが含まれるファイル一覧を取得した後、さらにfooが含まれるファイル一覧を吐き出す。

パイプをつないでいくとどんどんある特定の単語を含むファイルを絞っていける。

他に

$ git grep -l hoge | xargs sed -i -e 's/hoge/foo/g'

hogeが含まれるファイルを選択してfooに一括置換できて便利。


grep -vによる検索除外

$ git grep -n foo | grep -v bar

-nオプションをつけることで該当ファイルと行番号が出せるが、この時に例えばtest/ディレクトリ以下のものは検索したくないなと思った時にgrep -v testをパイプでつなぐと検索結果から削れる。

grep -vがgitとは関係ないことがミソ。無理に全部をオプションで解決するんじゃなくてパイプでがんがん繋ぐのが良い。


git add -pgit commit -v

git add -p は変更を加えたファイルのどの部分をindexにしたいか選びながらaddする。差分を適切な大きさでコミットするために使う。

加えて git commit -v はコミットを実行する前に、何をコミットしようとしているのか差分を確認してコミットメッセージを書くために使う。

両方とも一個一個のコミットを適切にするために使う。


git checkout で1ファイルだけ別のブランチから取ってくる

1ファイルだけ別のブランチから持ってくる に記載があるように

git checkout <ブランチ名> -- <ファイル名>

git checkout <ブランチ名> <ディレクトリ名> # ディレクトリでもいける


ローカルにあるブランチをリモートにある別名のブランチにpushする

以下のコマンドを叩くとローカルのAブランチをリモートのBブランチにpushできる(参考: git pushについて)

git push origin A:B


リモートブランチをローカルから消す

以下のコマンドでリモートのブランチを消せる。

git push --delete origin <ブランチ名>


コマンド再実行関連


昔実行したスクリプトを探す

$ history | grep hoge | tail

historyコマンドで昔実行したコマンド一覧が出せるが、その中から特定のスクリプトの実行履歴をgrepで出す(たとえばgrep mysqlとか)。でもよく実行するコマンドだとたくさん表示されてしまうのでtailとかで適当に削る。

本当によく使うコマンドならalias貼ればいいんじゃないの?とかCtrl + rで探せるやん?とかって話もあるが、私はaliasすら忘れるし、微妙に違う実行履歴がサジェストされる中からコマンド探すのが地味にストレスなので、適当にリスト出してくれるところから適当に選べるこれが脳みそに負担があまりかからなくて私には良い。!数字で再実行できるのも良い。

ただhistoryの実行結果には番号が振られてるのでsortuniqが使えないのがあまり良くない。シェルの環境設定ファイル(.bashrcとか.zshrcとか)で同じコマンドはhistoryに残さない設定をあらかじめ施しておくと多少省略可能。


forを使って複数サーバに同じコマンドを実行する

$ for h in host名のリスト do ssh $h "cat hogehoge"; done

これは危険なワンライナーだが使い方さえ間違えなければすごく便利。lsとかは便利だがrmは組み合わせてはいけない。本当に危ない。

tmuxで複数サーバにログインしながら同じコマンドを実行するとかできるけど、あれもやりすぎると何やってるか自分でわからなくなるので、使いすぎは禁物。


ファイル操作


あるファイルの件数を知る

$ sort hoge.txt | uniq | wc -l

これで hoge.txt に書かれた重複しない行数を調べることができる。

ただし hoge.txt のファイルの最後に改行がないと uniq 実行の時点で空行が最後に追加されるので、 wc -l の結果から -1 すること。

特に hoge.txt がuser_idのリストだったときに重宝する。 cut コマンドと組み合わせて特定行だけ抜き取ったファイルを作って調べるとかもよくやる。