Help us understand the problem. What is going on with this article?

変数展開時の単語分割(word split)をマスターする

More than 5 years have passed since last update.

シェルスクリプトは、スペース区切りの文字列が代入された変数を展開するとき、文字列をスペースの位置で分割して複数の文字列のように扱う。この挙動は Bash (をはじめとする Bourne shell 系のシェル)と Zsh とで異なってくる。

普通の変数について

Bash では、展開する変数をクォートしなければ単語分割が起きる。クォートすれば単語分割は起きず、スペースを含む1つの文字列として展開される。 Zsh では、変数をクォートするかしないかにかかわらず単語分割は起きない。ただし、 SH_WORD_SPLIT オプションをオンにすると Bash 準拠の挙動に変わる(デフォルトでオフ)。以下に単語分割の例を示す:

### 下準備

# 第1引数を echo する関数
function echo_first {
    echo $1
}

# スペース区切りの文字列を含む変数
var="a b c"



### Bash の場合

echo_first  $var  # => a
echo_first "$var" # => a b c

for v in $var; do
    echo $v
done
# => a
# => b
# => c

for v in "$var"; do
    echo $v
done
# => a b c



### Zsh (SH_WORD_SPLIT がオフ)の場合

echo_first  $var  # => a b c
echo_first "$var" # => a b c

for v in $var; do
    echo $v
done
# => a b c

for v in "$var"; do
    echo $v
done
# => a b c

Zsh で変数を強制的に単語分割するには ${=var} のように書く。記法の詳細ついては man zshexpn の "Parameter Expansion" を参照のこと。

特殊変数 $*$@ について

シェルスクリプトへのコマンドライン引数を格納する特殊変数 $*$@ は、それ自体がクォートされている場合の単語分割の挙動が異なる。 "$*" は、単語分割が起きずに1つの文字列として展開される。 "$@" は、引数に クォートされていないスペース が含まれる場合、そこで単語分割が起きる。

$* または $@ がクォートされていない場合、 Bash はスペースの位置で単語分割する。 Zsh はクォートされていないスペースの位置で単語分割する。

以下に例を示す:

wordsplit.sh
### クォートされたスペースを含む引数を与えて実行してみる

bash wordsplit.sh "a b" c
zsh  wordsplit.sh "a b" c



### Bash の場合

# $*: スペースで分割
for v in $*; do
    echo $v
done
# => a
# => b
# => c

# "$*": 分割なし
for v in "$*"; do
    echo $v
done
# => a b c

# $@: スペースで分割
for v in $@; do
    echo $v
done
# => a
# => b
# => c

# "$@": クォートされていないスペースで分割
for v in "$@"; do
    echo $v
done
# => a b
# => c



### Zsh (SH_WORD_SPLIT がオフ)の場合

# $*: クォートされていないスペースで分割
for v in $*; do
    echo $v
done
# => a b
# => c

# "$*": 分割なし
for v in "$*"; do
    echo $v
done
# => a b c

# $@: クォートされていないスペースで分割
for v in $@; do
    echo $v
done
# => a b c

# "$@": クォートされていないスペースで分割
for v in "$@"; do
    echo $v
done
# => a b
# => c
uasi
Qiita, Qiita:Team, Qiita Jobs を開発していました。趣味では Rust とシェルスクリプトをよく書きます。
http://uasi.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした