サーチ…


構文

  • IFSを改行に設定する:IFS = $ '\ n'
  • IFSをNULL文字列に設定します。IFS =
  • IFSを/文字に設定します。IFS = /

パラメーター

パラメータ詳細
IFS 内部フィールドセパレータ
-バツコマンドとそれらの引数を実行時に表示する(シェルオプション)

備考

  • ワードスプリットは割り当て中に実行されません。たとえば、 newvar=$var
  • 単語の分割は[[ ... ]]構文では実行されません
  • 単語分割を防ぐために変数に二重引用符を使用する

IFSによる分割

もっと明確にするために、 showargという名前のスクリプトを作成しましょう。

#!/usr/bin/env bash
printf "%d args:" $#
printf " <%s>" "$@"
echo

さて、違いを見てみましょう:

$ var="This is an example"
$ showarg $var
4 args: <This> <is> <an> <example>

$varは4つの引数に分割されます。 IFSは空白文字であるため、スペースで単語分割が発生しました

$ var="This/is/an/example"
$ showarg $var
1 args: <This/is/an/example>

IFS文字が見つからないため、上記の単語分割は行われませんでした。

今度は、 IFS=/

$ IFS=/
$ var="This/is/an/example"
$ showarg $var
4 args: <This> <is> <an> <example>

$varは1つの引数ではなく4つの引数に分割されています。

何、いつ、そしてなぜ?

シェルがパラメータ拡張コマンド置換変数または算術展開を実行すると、結果内の単語境界をスキャンします。単語境界が見つかった場合、結果はその位置で複数の単語に分割されます。単語境界は、シェル変数IFS (内部フィールドセパレータ)によって定義されます。 IFSのデフォルト値はスペース、タブ、改行です。つまり、明示的に禁止されていなければ、これら3つの空白文字で単語分割が行われます。

set -x
var='I am
a
multiline string'
fun() {
    echo "-$1-"
    echo "*$2*"
    echo ".$3."
}
fun $var

上記の例では、これはfun関数がどのように実行されているかです:

fun I am a multiline string

$varは5つの引数に分割され、 Iamaのみが出力されます。

IFSと単語分割

参照してください何を、いつ、なぜあなたは単語の分割にIFSの所属について知らない場合

IFSをスペース文字のみに設定しましょう:

set -x
var='I am
a
multiline string'
IFS=' '
fun() {
    echo "-$1-"
    echo "*$2*"
    echo ".$3."
}
fun $var

この時間分割はスペース上でのみ機能します。 fun関数は次のように実行されます:

fun I 'am
a
multiline' string

$varは3つの引数に分割されます。 I am\na\nmultilinestringが印刷されます

IFSを改行のみに設定しましょう:

IFS=$'\n'
...

今度のfunは次のように実行されます:

fun 'I am' a 'multiline string'

$varは3つの引数に分割されます。 I am 、 、 a multiline string印刷されます

IFSをNULL文字列に設定するとどうなるか見てみましょう:

IFS=
...

今回はfunことが次のように実行されます:

fun 'I am
a
multiline string'

$varは分割されていません。すなわち、1つのargのままです。

IFSをnullstringに設定すると、単語の分割を防ぐことができます

単語の分割を防ぐ一般的な方法は、二重引用符を使用することです。

fun "$var"

上記のすべてのケースで単語の分割を防止します。つまり、 fun関数は1つの引数のみで実行されます。

単語分割の悪影響

$ a='I am a string with spaces'
$ [ $a = $a ] || echo "didn't match"
bash: [: too many arguments
didn't match

[ $a = $a ][ I am a string with spaces = I am a string with spaces ] [ $a = $a ]と解釈されました。 [ I am a string with spacesあるtestコマンドは、単一の引数ではなく、むしろそれは6つの引数です!

$ [ $a = something ] || echo "didn't match"
bash: [: too many arguments
didn't match

[ $a = something ][ I am a string with spaces = something ]解釈されました

$ [ $(grep . file) = 'something' ]
bash: [: too many arguments

grepコマンドはスペースを含む複数行の文字列を返します。したがって、そこにいくつの引数があるのか​​想像できます:D

何のために、いつ、そしてなぜ基本的なのを見てください。

単語分割の有用性

単語の分割が便利な場合があります:

配列を埋める:

arr=($(grep -o '[0-9]\+' file))

これは、 ファイル内のすべての数値でarrを埋めます

スペースで区切られた単語をループする:

words='foo bar baz'
for w in $words;do
    echo "W: $w"
done

出力:

W: foo
W: bar
W: baz

空白を含まないスペースで区切られたパラメータを渡す:

packs='apache2 php php-mbstring php-mysql'
sudo apt-get install $packs

または

packs='
apache2
php
php-mbstring
php-mysql
'
sudo apt-get install $packs

これにより、パッケージがインストールされます。 $packsを二重引用符で囲むとエラーになります。

Unquoetd $packsapt-get引数としてスペースで区切られたすべてのパッケージ名を送信しますが、引用すると$packs文字列を単一の引数として送信し、 apt-getapache2 php php-mbstring php-mysqlというパッケージをインストールしようとしますapache2 php php-mbstring php-mysql明らかに存在しないapache2 php php-mbstring php-mysql (最初のもの)

何のために、いつ、そしてなぜ基本的なのを見てください。

セパレータの変更による分割

次の例のように、区切り記号をスペースから新しい行に簡単に置き換えることができます。

echo $sentence | tr " " "\n"

それは、可変sentence値を分割し、それをそれぞれ1行ずつ表示します。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow