本記事は zsh で*
を展開する方法について解説しています.
背景
bash や sh などのシェルではファイルを一括で処理したいとき,以下のようなスクリプトで対応できます.
#!/bin/bash
files="./*.txt"
for file in ${files}; do
echo ${file}
done
上記のスクリプトをsample.sh
として保存し,以下のようなディレクトリで実行した結果を見てみましょう.
ディレクトリ構造
. ├── 001.txt ├── 002.txt ├── 003.txt └── sample.sh
結果
./001.txt ./002.txt ./003.txt
for
文で一つずつ処理される際に*.txt
が展開されるため,指定したディレクトリ内の*.txt
ファイルに対して任意の操作ができます.
今回の例ではカレントディレクトリ内の*.txt
ファイルパスがecho
で表示されています.
シェルが zsh ではうまくいかない
ここでシェルをzsh
にする1と*.txt
の展開がうまくいかず以下のような結果になります.
#!/bin/zsh
files="./*.txt"
for file in ${files}; do
echo ${file}
done
./*.txt
結果を見ると*.txt
ファイルとして認識されており,意図する挙動ではないですね・・・
対応策
zsh
ではGLOB_SUBST
というオプションを有効にしないと*
などが展開されません.
有効にする方法は以下の3つがあります.
- 部分的に有効化
- シェルスクリプト単位で有効化
.zshenv
ファイル(設定ファイル)で全体に有効化
順に見ていきましょう.
部分的に有効化
~
オプションを変数につけることで部分的にGLOB_SUBST
を有効化することができます.
具体的には以下のように記載します.
#!/bin/zsh
files="./*.txt"
for file in ${~files}; do # filesの前に ~オプションを付与
echo ${file}
done
./001.txt ./002.txt ./003.txt
*.txt
が展開され,意図した挙動となりました!
シェルスクリプト単位で有効化
GLOB_SUBST
を有効にしたいシェルスクリプトに以下の内容を記載します.
setopt GLOB_SUBST
#!/bin/zsh
setopt GLOB_SUBST # 追記
files="./*.txt"
for file in ${files}; do
echo ${file}
done
./001.txt ./002.txt ./003.txt
シェルスクリプト全体でGLOB_SUBST
が有効になるため~
オプションを付けなくても bash や sh と同一の記載で展開されるようになります.
.zshenv
ファイル(設定ファイル)で全体に有効化
最後に.zshenv
2に追記する方法です.
.zshenv
に以下の内容を追記して有効化すれば,永続的な設定が全体に適用されます.
setopt GLOB_SUBST
有効化のコマンド3は以下です.
(成功しても何も表示されません)
echo setopt GLOB_SUBST >> ~/.zshenv && source ~/.zshenv
上記のコマンドを実行後は bash や sh と同じように記載することができます.
#!/bin/zsh
files="./*.txt"
for file in ${files}; do
echo ${file}
done
./001.txt ./002.txt ./003.txt
ひとこと
bash と zsh の差は色々とありますね.
どちらでもいい感じに書けるようになりたい・・・