拡張子がないファイルを見つけて削除するスクリプトを作成する
Table of Contents
拡張子なしのファイルを削除したい
C, C++, Rustなどのちょっとしたコードを書いて実行するという場合、コンパイル時に(何も指定しなければ)拡張子なしの実行ファイルが生成されます。僕の場合は、競技プログラミングの問題を解く場合や、ちょっとしたお遊びコードを書く場合とかに気づいたら作業ディレクトリが実行ファイルで溢れていたりします。
今回はそのような拡張子のないファイルを見つけてガッと削除するコマンドを作成しよう、という記事です。
なお、この記事では拡張子のないファイルというのは、ファイル名が<filename>.<ext>
という形式になっていないファイルを指すことにします。
拡張子がないファイルを正規表現で判定
まずは拡張子のないファイルを発見するコマンドを確認します。今回はgrepを使用することにします。grepで拡張子が指定されていないファイルを見つけるには以下のコマンドが使用できます。
$ grep -v -E '^.+\..+$'
-v
オプションはマッチしないものを返す際に使用するオプションで、-E <regexp>
はマッチに使用する正規表現を指定するオプションです。つまり、正規表現 '^.+\..+$'
にマッチしないものを返すようなコマンドということです。正規表現部分は、文字列先頭から末尾までに.
が一つ以上含まれているような文字列にマッチするように記述されています。
検索候補をgrepに渡してから削除
検索対象とするファイル名をgrepに渡します。一番単純なのは、現在のディレクトリ内のファイルを全て与えるような方法です。
$ ls . | grep -v -E '^.+\..+$'
一見よさそうに見えますが、実はこのままでは不十分です。というのもlsコマンドではディレクトリも一緒に出力されてしまうためです。そこでlsコマンドに-F
オプションをつけてディレクトリ名の末尾に/
を追加するようにします(実行可能ファイルには末尾に*
がつきます)。そしてgrepコマンドでそのような名前を弾きます。
$ ls -F . | grep -v -E '^.+/$' | grep -v -E '^.+\..+$'
最後にgrepでフィルターしたファイル名を引数にしてxargsでrmコマンドを実行します。-F
オプションをつけたことによって実行可能ファイル名に追加される*
をsedコマンドで削除しています。実行する際は今のディレクトリをよく確認して実行してください。
$ ls -F . | grep -v -E '^.+/$' | grep -v -E '^.+\..+$' | sed s/\*$//g | xargs -I{} rm {}
実行可能コマンドとして配置する
よく実行する場合は、実行可能コマンドとして作業環境に用意しておくと便利です。僕の場合はrmx
というファイル名で以下のようなコマンドを用意しています(コピペで使用可能です)。思わぬ事故を防ぐために、削除予定のファイル名を出力してyes/noを訪ねてから実行するようにしています。
#!/bin/bash
function file_list() {
ls -F $1 | grep -v -E '^.+/$' | grep -v -E '^.+\..+$' | sed s/\*$//g
}
function run_rmx() {
file_list | xargs -I{} rm {}
}
file_list
read -p "> delete these files? (y/N): " answer
case $answer in
[yY]*) run_rmx;;
*) echo "aborted";;
esac
このファイルを適当な場所に置いて、権限を変更し、PATHを通したら完了です。
$ sudo chmod 755 rmx
# ~/binにrmxを置いている場合。.bashrcとか.zshrcに書いておくと良いです。
$ export PATH="$HOME/bin:$PATH"
コマンド実行例
ディレクトリを指定して削除可能です。よく拡張子なしファイルを消してまわる人には便利ですね。
$ rmx .
ABC327C
ABC327E
> delete these files? (y/N): y
僕のユースケースではこれで事足りていますが、再帰的にディレクトリを潜って探索したい場合はfind等を使用すると良いでしょう(その場合は正規表現等を修正する必要があります)。