grepのようにfindする

findコマンドのオプション指定が面倒なので、grepのように使える、次のようなシェル関数を定義してみる。

if [[ -n "$PS1" ]]; then
    f() {
        find "${2:-.}" \! -type d \! -path "*/.*" -path "*$1*" |& grep -v -F ": Permission denied" | sort
    }
fi

このコマンドは、第2引数に指定したディレクトリ以下について、フルパスに第1引数を含むものをソートして表示する。 また、一致するもののうち、ディレクトリそのもの、ドットから始まる隠しディレクトリ以下は除外する。 合わせて、パーミッションがないことによるエラーメッセージを出ないようにしている。

なお、第2引数を省略した場合はカレントディレクトリが対象となり、第1引数も省略した場合は除外条件を除くすべてのファイルが表示される。

grepのようにフルパスからマッチするものを探せて便利。

$ f interface /etc
/etc/apparmor/init/network-interface-security/sbin.dhclient
/etc/init/network-interface-container.conf
/etc/init/network-interface-security.conf
/etc/init/network-interface.conf
/etc/network/interfaces
/etc/resolvconf/interface-order

$ f auth /var
/var/lib/dpkg/info/xauth.list
/var/lib/dpkg/info/xauth.md5sums
/var/lib/pam/auth
/var/log/auth.log
/var/log/auth.log.1
/var/log/auth.log.2.gz
/var/log/auth.log.3.gz
/var/log/auth.log.4.gz

より詳細な情報を得るには次のようにすればよい。

$ ls -l $(f sh /bin)
-rwxr-xr-x 1 root root 1021112 Sep 27 17:04 /bin/bash*
-rwxr-xr-x 1 root root  121272 Feb 19  2014 /bin/dash*
lrwxrwxrwx 1 root root       4 Sep 27 17:04 /bin/rbash -> bash*
lrwxrwxrwx 1 root root       4 Oct  6 22:15 /bin/sh -> dash*
lrwxrwxrwx 1 root root       4 Oct  6 22:15 /bin/sh.distrib -> dash*
lrwxrwxrwx 1 root root       7 Nov 15  2013 /bin/static-sh -> busybox*

想定問答集

  • locateコマンドを使えばよいのでは
    • たまにしか起動しない仮想マシンで毎回sudo updatedbを打ちたくない
  • shopt -s globstar、あるいはzshを使って**を利用すればよいのでは
    • ls -ld /**/*interface*のような指定をしたくない