awk
Git
ワンライナー
AkatsukiDay 13

複数の不定パターンのファイル名を指定するワンライナー `nf`

More than 1 year has passed since last update.

この記事は Akatsuki Advent Calendar 2016 の13日目です。


はじめに

Advent Calendar でワンライナー紹介もなんだか、、と思ったのですが、以前に若手エンジニアに教えたら感心していたので紹介します。ちなみに私の回りのディレクターもいつも使っています。


さっそく実例

git で以下のように変更があったとします。

image

このうち、 csv/battle_comments.csv, csv/battle_periods.csv, csv/battles.csv の 3 つのみを add したいとします。

この場合、普通は以下のようなコマンドラインになります。

$ git add csv/battle_comments.csv csv/battle_periods.csv csv/battles.csv

長いです!!! ファイル名の正確なコピペが辛いです。ワイルドカードでもう少し省略して書くこともできますが、面倒くさいです。いちいちエディタを起動して、コマンドラインを組み立てるのも手間です。

自分は以下のようにします。

$ git add `awk '{print $NF}'`

上記を実行すると入力待ちになるので、 add したいファイル名を含む行をまとめてコピペして、最期に行頭にカーソルがある状態で CTRL+D を押します。一瞬 ^D が表示された後、プロンプトに戻って 3 つのファイルが add された状態になります。

一応実行した時のキャプチャも貼り付けておきます。

image

動作原理としては、標準入力より awk によって、最期のフィールドだけを取り出して(print $NF)、それを shell のコマンド置き換え機能で git に渡しているということです。

意外と shell のコマンド置き換え機能で改行がスペースに変換されるということを知らない人は多く、これがわからないとなぜ動作するのかもわかりづらいと思います。


コマンド化してみる

毎度上記の如くタイプしても良いわけですが、ちょっとでもタイプ量を減らすために

git add `nf`

だけで実行できるようにします。いくつかの方法で実装しますが、せっかくなので shell script で実装するものは何番目のフィールドを取り出すかも指定できるようにしてみます。


alias(awk, フィールド番号指定不可)

alias nf='awk "{print $NF}"'


alias(ワンライナー ruby, フィールド番号指定不可)

alias nf="ruby -a -n -e 'puts "'$F'".last'"


shell script(awk, フィールド番号指定可)

#!/bin/sh


if [ "$1" != "" ] ; then
exec awk '{print $'$1'}'
else
exec awk '{print $NF}'
fi


当然 git 以外とも組み合わせて使える

自分はこれを rm コマンドと組み合わせて untracked ファイルの削除などにも使っています。

@sachaos と話をしていたら、 git clean でもそれができると知りました。

それはそれでありなのですが、コマンドの組み合わせで解決できれば、他にも応用が効くかと思います。


終わりに

単純なワンライナーの話でしたが何かの参考になれば幸いです。