こんにちは、河野です。
CとかGolangとか、コンパイルする言語を扱っていると、コンパイル後の実行形式ファイルが出来るのですが、gitなどでコード管理する際には邪魔なので、削除したくなります。
以下、Cを勉強中のフォルダです。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36  | 
						% ls -l 合計 152 -rwxr-xr-x 1 kawaken kawaken 7157  1月 23 12:53 2014 a.out* -rw-r--r-- 1 kawaken kawaken  344  1月 20 12:43 2014 bermuda.c -rwxr-xr-x 1 kawaken kawaken 7297  1月  6 12:46 2014 cards* -rw-r--r-- 1 kawaken kawaken  809  1月  6 12:49 2014 cards.c -rwxr-xr-x 1 kawaken kawaken 7655  1月 22 12:18 2014 categorize* -rw-r--r-- 1 kawaken kawaken  775  1月 22 12:36 2014 categorize.c -rw-r--r-- 1 kawaken kawaken  243  1月  8 12:44 2014 contestants.c -rw-r--r-- 1 kawaken kawaken  393  1月 23 12:40 2014 data_size.c -rw-r--r-- 1 kawaken kawaken  124  1月 24 12:54 2014 encrypt.c -rw-r--r-- 1 kawaken kawaken   29  1月 24 12:53 2014 encrypt.h -rw-r--r-- 1 kawaken kawaken  187  1月 10 12:29 2014 food.c -rw-r--r-- 1 kawaken kawaken  653  1月 16 12:49 2014 geo2json.c -rw-r--r-- 1 kawaken kawaken  481  1月 16 12:47 2014 gpsdata.csv -rw-r--r-- 1 kawaken kawaken  382  1月 10 12:49 2014 jimmy.c -rw-r--r-- 1 kawaken kawaken   38  1月 20 12:27 2014 message1.txt -rw-r--r-- 1 kawaken kawaken   27  1月 20 12:27 2014 message2.txt -rwxr-xr-x 1 kawaken kawaken 6859  1月 24 12:56 2014 message_hider* -rw-r--r-- 1 kawaken kawaken  151  1月 24 12:55 2014 message_hider.c -rw-r--r-- 1 kawaken kawaken  227  1月 10 12:41 2014 monte.c -rw-r--r-- 1 kawaken kawaken  438  1月  9 18:55 2014 name_test.c -rwxr-xr-x 1 kawaken kawaken 7448  1月 22 12:51 2014 order_pizza* -rw-r--r-- 1 kawaken kawaken  674  1月 22 12:50 2014 order_pizza.c -rw-r--r-- 1 kawaken kawaken  176  1月  6 13:00 2014 pointer.c -rw-r--r-- 1 kawaken kawaken  707  1月 15 12:56 2014 reverse.c -rw-r--r-- 1 kawaken kawaken  242  1月 20 12:26 2014 secret.c -rw-r--r-- 1 kawaken kawaken   65  1月 20 12:27 2014 secret.txt -rw-r--r-- 1 kawaken kawaken  141  1月  8 18:58 2014 skip.c -rw-r--r-- 1 kawaken kawaken  279  1月  7 12:48 2014 southeast.c -rw-r--r-- 1 kawaken kawaken  358  1月 20 12:41 2014 spooky.csv -rw-r--r-- 1 kawaken kawaken  784  1月 23 12:53 2014 totaller.c -rw-r--r-- 1 kawaken kawaken   29  1月 23 12:53 2014 totaller.h -rw-r--r-- 1 kawaken kawaken  587  1月 15 12:32 2014 tracks.c -rw-r--r-- 1 kawaken kawaken  516  1月 23 12:35 2014 waiter.c  | 
					
削除したいのは、この中の*が付いている以下の5つのファイルです。
| 
					 1 2 3 4 5  | 
						a.out cards categorize message_hider order_pizza  | 
					
ファイルを探す
findですが、-executableというオプションがあります。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						% find . -executable . ./cards ./a.out ./message_hider ./order_pizza ./.git ./.git/objects ./.git/objects/58 ./.git/objects/00 ./.git/objects/pack (省略)  | 
					
と実行してみると、ディレクトリも含まれてしまいました。あと、gitディレクトリも含まれていますね。
-executable というのは実行権限が付いているものが対象になるようです。なのでディレクトリも含まれてしまうということですね。-typeで絞り込みます。
| 
					 1 2 3 4 5 6 7 8 9  | 
						% find . -executable -type f ./cards ./a.out ./message_hider ./order_pizza ./.git/pre-commit ./.git/hooks/pre-commit ./categorize  | 
					
これでディレクトリは除外されましたが、.git配下のhookスクリプトも引っかかってしまいました。
grep で除去
grepで除去するのが直感的な気がします。
| 
					 1 2 3 4 5 6 7  | 
						% find . -executable -type f | grep -v .git ./cards ./a.out ./message_hider ./order_pizza ./categorize  | 
					
問題ないですね。findではできないのでしょうか。
pathで絞り込み
find の pathオプションを使うと、ファイルのパスに含まれる文字列を指定できます。これにnotを組み合わせることで、.gitが含まれないものが取得できます。
| 
					 1 2 3 4 5 6 7  | 
						% find . -executable -type f -not -path '*.git*' ./cards ./a.out ./message_hider ./order_pizza ./categorize  | 
					
同じ結果になりました。
ファイルの削除
grepで絞り込んだ場合は、さらにパイプでxargsに渡すのが良いでしょうか。
| 
					 1  | 
						% find . -executable -type f | grep -v .git | xargs rm  | 
					
find で絞り込んだ場合には、さらにdeleteオプションで対応できそうです。
| 
					 1  | 
						% find . -executable -type f -not -path '*.git*' -delete  | 
					
実行したら綺麗に消えました。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30  | 
						 ls -l 合計 112 -rw-r--r-- 1 kawaken kawaken 344  1月 20 12:43 2014 bermuda.c -rw-r--r-- 1 kawaken kawaken 809  1月  6 12:49 2014 cards.c -rw-r--r-- 1 kawaken kawaken 775  1月 22 12:36 2014 categorize.c -rw-r--r-- 1 kawaken kawaken 243  1月  8 12:44 2014 contestants.c -rw-r--r-- 1 kawaken kawaken 393  1月 23 12:40 2014 data_size.c -rw-r--r-- 1 kawaken kawaken 124  1月 24 12:54 2014 encrypt.c -rw-r--r-- 1 kawaken kawaken  29  1月 24 12:53 2014 encrypt.h -rw-r--r-- 1 kawaken kawaken 187  1月 10 12:29 2014 food.c -rw-r--r-- 1 kawaken kawaken 653  1月 16 12:49 2014 geo2json.c -rw-r--r-- 1 kawaken kawaken 481  1月 16 12:47 2014 gpsdata.csv -rw-r--r-- 1 kawaken kawaken 382  1月 10 12:49 2014 jimmy.c -rw-r--r-- 1 kawaken kawaken  38  1月 20 12:27 2014 message1.txt -rw-r--r-- 1 kawaken kawaken  27  1月 20 12:27 2014 message2.txt -rw-r--r-- 1 kawaken kawaken 151  1月 24 12:55 2014 message_hider.c -rw-r--r-- 1 kawaken kawaken 227  1月 10 12:41 2014 monte.c -rw-r--r-- 1 kawaken kawaken 438  1月  9 18:55 2014 name_test.c -rw-r--r-- 1 kawaken kawaken 674  1月 22 12:50 2014 order_pizza.c -rw-r--r-- 1 kawaken kawaken 176  1月  6 13:00 2014 pointer.c -rw-r--r-- 1 kawaken kawaken 707  1月 15 12:56 2014 reverse.c -rw-r--r-- 1 kawaken kawaken 242  1月 20 12:26 2014 secret.c -rw-r--r-- 1 kawaken kawaken  65  1月 20 12:27 2014 secret.txt -rw-r--r-- 1 kawaken kawaken 141  1月  8 18:58 2014 skip.c -rw-r--r-- 1 kawaken kawaken 279  1月  7 12:48 2014 southeast.c -rw-r--r-- 1 kawaken kawaken 358  1月 20 12:41 2014 spooky.csv -rw-r--r-- 1 kawaken kawaken 784  1月 23 12:53 2014 totaller.c -rw-r--r-- 1 kawaken kawaken  29  1月 23 12:53 2014 totaller.h -rw-r--r-- 1 kawaken kawaken 587  1月 15 12:32 2014 tracks.c -rw-r--r-- 1 kawaken kawaken 516  1月 23 12:35 2014 waiter.c  | 
					
それzshなら一発でできるよ!
ちなみにzshだと、ファイル指定が豊富なので、rmコマンドだけで対応できます。
例えばlsだと、
| 
					 1 2 3  | 
						% ls *(*) a.out*  cards*  categorize*  message_hider*  order_pizza*  | 
					
こんな感じです。
後ろに付けている括弧のなかでファイルの種類が指定できます。
* … 実行形式ファイル
@ … シンボリックリンク
/ … ディレクトリ
などなど。
rmで使う場合には、以下のようになります。
| 
					 1 2 3 4 5 6 7  | 
						% rm -i *(*) rm: remove 通常ファイル `a.out'? y rm: remove 通常ファイル `cards'? y rm: remove 通常ファイル `categorize'? y rm: remove 通常ファイル `message_hider'? y rm: remove 通常ファイル `order_pizza'? y  | 
					
さすがzshですね!
まとめ
というわけで、みんなzsh使いましょう!


Comments
それ、.gitignoreに少し記述足すだけでいいのでは…
そうですね。特定のファイル(a.out)とかなら.gitignoreでコミット対象外にした方良いと思います。
今回は.gitignoreを使わずに解決したかったので、上記の方法を模索していました。