Linuxでextglobを有効にして「指定したパターン以外のファイル」を指定する
Pocket

仕事などで日常的にLinuxを利用しているのであれば、ほぼ大半の人がglobを利用した事があるだろう。
globという名前にはあまり馴染みが無いかもしれないが、以下のようにワイルドカードや複数のファイル名を指定したりする機能は使ったことがあるはずだ。

例)「/work」フォルダ配下のファイルを「/work2」に移動する

mv /work/* /work2/

 

例)「/work」フォルダ配下の「aaa.txt」「bbb.txt」のみを削除する

rm /work/{aaa.txt,bbb.txt}

 

このような指定方法を可能にしているのがglobという機能になる。
そんなglobを拡張したのが、今回紹介するextglobだ。

このextglobを利用すると、globでは指定が難しかった事、例えば”特定のフォルダ以外を指定する”といった事が簡単に行える。
bashやzshで有効になっているかどうか確認するには、以下のようにコマンドを実行する。有効になっていれば、以下のように出力されるはずだ。

●bashの場合

shopt | grep extglob
test@test-vm-ubuntu:~$ shopt | grep extglob
extglob         on

 

●zshの場合

setopt | grep extendedglob
test-vm-ubuntu% setopt | grep extendedglob
extendedglob
Sponsored Links

もしextglobが有効になっていないならば、以下のようにコマンドを実行して有効化する。
常時利用するならば、bashrcなどに記述しておいても良いだろう。

●bashの場合

shopt -s extglob

 

●zshの場合

setopt extendedglob

 

さて、これでextglobが利用できるようになった。
extglobでは、以下のようにパターン指定を行う。

  • ?(パターン) … 指定したパターンに一致するものを指定
  • *(パターン) … 指定したパターンを0回以上繰り返すものを指定
  • +(パターン) … 指定したパターンを0回以上繰り返すものを指定
  • @(パターン) … 指定したパターンのいずれかに一致するものを指定
  • !(パターン) … 指定したパターンに該当しないものを指定

この中でも特に注目すべきは、「!(パターン)」だろう。
それ以外のものは通常のglobでも指定可能だが、「!(パターン)」に関しては通常のglobでは指定出来ない。

実際に、指定パターン以外のファイルを抽出してみよう。
「/work」フォルダにある、「test.txt」以外のファイルを抽出する。

ls -la /work/!(test.txt)

20150606_000003

[root@test-centos7 ~]# ls -la /work
合計 16
drwxr-xr-x.  2 root root 4096  6月  6 12:14 .
drwxr-xr-x. 18 root root 4096  6月  4 06:18 ..
-rw-r--r--.  1 root root    0  6月  6 12:14 aaaaa.txt
-rw-r--r--.  1 root root    0  6月  6 12:14 bbbbb.txt
-rw-r--r--.  1 root root    0  6月  6 12:14 ccccc.txt
-rw-r--r--.  1 root root    0  6月  6 12:14 ddddd.txt
lrwxrwxrwx.  1 root root    8  6月  5 19:29 ln_test.txt -> test.txt
lrwxrwxrwx.  1 root root   17  6月  5 19:30 ln_test.txt2 -> /work/ln_test.txt
-rw-r--r--.  1 root root  108  6月  4 22:31 test.txt
-rw-r--r--.  1 root root  230  6月  4 07:17 test2.txt
[root@test-centos7 ~]# ls -la /work/!(test.txt)
-rw-r--r--. 1 root root   0  6月  6 12:14 /work/aaaaa.txt
-rw-r--r--. 1 root root   0  6月  6 12:14 /work/bbbbb.txt
-rw-r--r--. 1 root root   0  6月  6 12:14 /work/ccccc.txt
-rw-r--r--. 1 root root   0  6月  6 12:14 /work/ddddd.txt
lrwxrwxrwx. 1 root root   8  6月  5 19:29 /work/ln_test.txt -> test.txt
lrwxrwxrwx. 1 root root  17  6月  5 19:30 /work/ln_test.txt2 -> /work/ln_test.txt
-rw-r--r--. 1 root root 230  6月  4 07:17 /work/test2.txt

 

複数のパターンを指定する場合は、「|(パイプ)」で指定を行う。
例えば、「aaaaa.txt」および「bbbbb.txt」以外を抽出する場合は以下のようにコマンドを実行する。

ls -la /work/!(aaaaa.txt|bbbbb.txt)

20150606_000004

[root@test-centos7 ~]# ls -la /work
合計 16
drwxr-xr-x.  2 root root 4096  6月  6 12:14 .
drwxr-xr-x. 18 root root 4096  6月  4 06:18 ..
-rw-r--r--.  1 root root    0  6月  6 12:14 aaaaa.txt
-rw-r--r--.  1 root root    0  6月  6 12:14 bbbbb.txt
-rw-r--r--.  1 root root    0  6月  6 12:14 ccccc.txt
-rw-r--r--.  1 root root    0  6月  6 12:14 ddddd.txt
lrwxrwxrwx.  1 root root    8  6月  5 19:29 ln_test.txt -> test.txt
lrwxrwxrwx.  1 root root   17  6月  5 19:30 ln_test.txt2 -> /work/ln_test.txt
-rw-r--r--.  1 root root  108  6月  4 22:31 test.txt
-rw-r--r--.  1 root root  230  6月  4 07:17 test2.txt
[root@test-centos7 ~]# ls -la /work/!(aaaaa.txt|bbbbb.txt)
-rw-r--r--. 1 root root   0  6月  6 12:14 /work/ccccc.txt
-rw-r--r--. 1 root root   0  6月  6 12:14 /work/ddddd.txt
lrwxrwxrwx. 1 root root   8  6月  5 19:29 /work/ln_test.txt -> test.txt
lrwxrwxrwx. 1 root root  17  6月  5 19:30 /work/ln_test.txt2 -> /work/ln_test.txt
-rw-r--r--. 1 root root 108  6月  4 22:31 /work/test.txt
-rw-r--r--. 1 root root 230  6月  4 07:17 /work/test2.txt

 

変に長いコードを記述するよりは、このような機能を使って短縮してわかりやすいコードを書いたほうがいいだろう。

Written by blacknon

インフラ系のSE。一時期はプログラマ。 仮想化とオープンソースに興味あり。一日中寝てたい今日このごろ。 スペインとかで働きたいなぁ…(シエスタがあるので)

Leave a Comment

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>