雑にシェルスクリプトのみを一覧取得するコマンド
ファイル名に拡張子 .sh
が付いていれば見つけるのは簡単だが、拡張子なしのファイルも見つけたかったので、試行錯誤をメモ。
最初に結論
$ grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1 | grep -v .git
試行錯誤
shebangで検索
$ grep '^#!' -rl .
行頭が #!
ではじまるファイルを探している。
あんまりこれで困らないと思うが、欠点も存在する。一行目ではなく、ファイルの途中に #!
があっても拾ってしまうのだ。
一行目のみに絞り込む
$ grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1
最初のgrepで行番号も出力している。たとえば、こんな感じで出力される。
$ grep '^#!' -rn . ./install:1:#!/bin/sh ./README.md:33:#!/bin/sh ./hooks/build:1:#!/bin/bash
そして、 :1:#!
でgrepかけて、一行目に含まれているファイル一覧に絞り込む。
$ grep '^#!' -rn . | grep ':1:#!' ./install:1:#!/bin/sh ./hooks/build:1:#!/bin/bash
最後にファイル名だけ取り出す。
$ grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1 ./install ./hooks/build
.gitを除外
$ grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1 | grep -v .git
git 管理してるディレクトリ配下で実行すると .git
ディレクトリ内も検索してしまう。そこで、単純に -v
オプションで .git
ディレクトリ配下を除外する。
おまけ:Makefile内で使う
最初、Makefileで定義するにあたって、普通にshell関数内で実行して、その結果を変数に格納していたが、なぜかshell関数は、実行結果の改行を空白に置換してしまって困った。
仕方ないのでマクロ定義して、それを呼び出すことにした。
define list_shellscript grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1 | grep -v .git endef
で、使うときはこんな感じ。
$(call list_shellscript)
xargsと組み合わせるときも、こんな感じで書ける。
$(call list_shellscript) | xargs -I {} echo {}