UNIX/Linuxのシェルの1つであるshやbashの演算子には、代入演算子、算術演算子、数値比較演算子、文字列比較演算子、論理演算子、条件演算子(三項演算子)、シフト演算子、ビット演算子、ファイル演算子、グループ化演算子、パターンマッチ演算子などがあります。
bashにはtrue/falseの真偽値を結果として返すファイル判定を行う演算子があります。
| ファイル判定演算子 | 使用法 | true条件 |
|---|---|---|
| -a | -a file | fileが存在する |
| -b | -b file | fileがブロック特殊ファイル |
| -c | -c file | fileが文字特殊ファイル |
| -d | -d file | fileがディレクトリ |
| -e | -e file | fileが存在する |
| -f | -f file | fileが存在し、且つ一般的なファイル |
| -g | -g file | fileがset-group-id/setgid/sgid |
| -h | -h file | fileがシンボリックリンク |
| -L | -L file | fileがシンボリックリンク |
| -k | -k file | fileがstickyビットセットを持つ |
| -p | -p file | fileが名前付きパイプ |
| -r | -r file | fileが読み取り可 |
| -s | -s file | fileが存在し、且つカラではない |
| -S | -S file | fileがソケット |
| -t | -t FD | FD(ファイルディスクリプタ)が端末上で開かれている |
| -u | -u file | fileがset-user-id/setuid/suid |
| -w | -w file | fileが書き込み可 |
| -x | -x file | fileが実行可 |
| -O | -O file | fileの所有者が自分(uidが一致) |
| -G | -G file | fileが所有者が自グループ(gidが一致) |
| -N | -N file | fileが前回読み取り後に修正されている(更新日時が最終アクセス日時より後) |
| -ef | file1 -ef file2 | file1がfile2へのハードリンク |
| -nt | file1 -nt file2 | newer than/file1がfile2よりも新しい |
| -ot | file1 -ot file2 | older than/file1がfile2よりも古い |
bashではコマンドセパレータ ; (セミコロン)で区切られたコマンドのリストをカレントシェルでグループ化する ( ) やリストとしてサブシェルでグループ化する { } というグループ化演算子があります。
| グループ化演算子 | 意味 |
|---|---|
| ( ) | カレント(現在の)シェルでグループ化 |
| { } | サブシェルでグループ化 |
まず、echoコマンドで { } に開始と終了の範囲として数値またはアルファベットをドット・ピリオド2つを挟んで入れるとそのリストが標準出力に出力されます。
( )については、例えば、bashでは複数のshellコマンドを ; (セミコロン)で区切って一行で記述することができますが、それだけでは、この例のようにそれぞれのコマンドの効果が適用されず、最後のコマンドだけが有効になってしまう場合があります。
この例はリダイレクトしなかった最初のsedコマンドの結果が標準出力に出力され、次の2つめのsedコマンドの結果がリダイレクトによってbarに書き込まれただけで期待する結果にはなっていません(最初のsedでリダイレクトすると標準出力には出力されなくなるだけでcat barの結果は同じです)。
一方、この例のようにそれぞれのsedでリダイレクトを使い、2回めを追加書き出しすれば何れのsedコマンドの結果も出力されているのであとはコマンド処理結果だけを出力できればなんとかなりそうです。
そこでsedでは-nオプションとpコマンドを併用すると結果行だけを表示する事ができるので、それに加え2つめ(以降)のsedコマンドの結果を追加書き出しでリダイレクトすれば期待する結果を得ることができます。
ただ、このようにグループ化演算子を利用すると1度のリダイレクトで済む分、よりスマートに記述することができ、この( )の場合そのシェル上で、{ }の場合はサブシェル上でセミコロンで区切られたコマンドの実行結果が順次反映されるようになります。
( ) によるグループ化演算子の一例としてsedを取り上げましたが、実はsedには、この例のケースにおいては、よりベターと思われる-eオプションを利用する方法があります。
sedには1つのsedコマンドでエラーメッセージを抑止しつつ複数(単一も可)の処理を行う-eオプションがあり、-eオプションの場合、1つのsedに指定できるのでコマンドセパレータのセミコロンやグループ化する ( ) も要りませんし、(同じファイルの編集のはずなので)入力ファイルの記述も1つでよく、より短くコマンドを記述できます。
但し、-eオプションは次に来る入力をsedコマンドとして引数に取るので-nオプションと-eオプションを併用する場合には、-nオプションを先に指定しないと期待通りの結果にはなりません。
bashでは正規表現、パターンマッチを使用することができ、標準パターンは下記の通りです。
| パターンマッチ演算子 | 意味 |
|---|---|
| * | null文字を含むなんらかの文字列にマッチ |
| ? | なんらかの単独の1文字にマッチ |
| [...] | "["と"]"の中で指定された範囲にマッチ 言語指定とシェル変数LC_COLLATEの値による 標準では[a-z][A-Z][a-cx-z][0-9]...etc. |
| [: CLASS :] |
※[: CLASS :]で利用できるクラスは、POSIXクラスです。
| POSIX | 非POSIX | Perl | ASCII | 意味 |
|---|---|---|---|---|
| [: alnum :] | [A-Za-z0-9] | アルファベットと数値にマッチ | ||
| [: alpha :] | [A-Za-z] | アルファベットにマッチ | ||
| [: upper :] | [A-Z] | 大文字にマッチ | ||
| [: lower :] | [a-z] | 小文字にマッチ | ||
| [: digit :] | \d | [0-9] | 10進整数にマッチ | |
| \D | [^0-9] | 10進整数以外にマッチ | ||
| [: xdigit :] | [A-Fa-f0-9] | 16進数にマッチ | ||
| [: blank :] | [ \t] | 空白とタブにマッチ | ||
| [: space :] | \s | [ \t\n\v\f] | 空白にマッチ | |
| \S | [^ \t\n\v\f] | 空白以外にマッチ | ||
| [: cntrl :] | [\x00-\x1F\x7F] | 制御文字にマッチ | ||
| [: graph :] | [\x21-\x7E] | 印字文字にマッチする | ||
| [: print :] | [\x20-\x7E] | 印字文字と空白にマッチ | ||
| [: punct :] | [][!"#$%&'()*+,./:;<=>?@\^_`{|}?-] | 句読点特殊文字(特殊記号)にマッチ | ||
| [: word :] | \w | [A-Za-z0-9_] | アルファベットと数値とアンダースコアにマッチ | |
| \W | [^A-Za-z0-9_] | アルファベットと数値とアンダースコア以外にマッチ |
また、互換性の問題があるかもしれませんが、bashでは、shopt(shell option)コマンドでextglob(extension glob)オプションを有効にすれば下記の拡張パターンマッチングを利用できます。
| パターンマッチ演算子 | 意味 |
|---|---|
| ?(PATTERN-LIST) | ゼロ回または1回マッチ |
| *(PATTERN-LIST) | ゼロ回以上マッチ |
| +(PATTERN-LIST) | 1回以上マッチ |
| @(PATTERN-LIST) | 1回マッチ |
| !(PATTERN-LIST) | パターン以外の何かにマッチ |
PATTERN-LISTは、|(縦棒)で区切られた複数のパターンを持つことが可能で複数ある場合はその各パターンを評価します。
shoptコマンドは、set、env、printenvのようにコマンドラインからshoptと打って[Enter]で一覧を取得でき、設定はスイッチオプションで行います。
$ shopt # 表示
$ shopt -p # 表示
$ shopt -q # 表示抑止
$ shopt -s OPTION # 設定(on)
$ shopt -u OPTION # 解除(off)
再ログイン時にも有効にしたい場合には、ホームディレクトリの設定ファイル~/.bashrcに記述します。