Bashでの$IFSの使い方は?
IFSはInternal Field Separatorの略で、シェルの環境変数で区切り文字を決定します。$IFSはコマンドプロンプト上の単語がどのように区切られているかを指定します。デフォルトでは、フィールド区切り文字(IFS)はスペース、タブ、改行ですが、これをスクリプトで変更して要件に合わせることができます。主に指定されたリスト内の要素を操作するためのループに使用されます。Bashスクリプトで文字列を分割するために$IFS変数を使用します。Bashには文字列分割のための組み込み機能がないからです。
例1: $IFSオペレーターなしのBashスクリプト
以下のBashスクリプトを考えてみましょう。ここでは、要素が空白で区切られています。通常のBashスクリプトの出力を見るために、$IFS演算子は使用していません。まず、“Bash.sh”ファイルを作成し、次にプログラムを書くために開き、Bashシェルに文字列を出力します。まず、“$MySentence”というタイトルの変数を宣言し、この変数に長い文字列を指定します。文字列には、空白で区切られたさまざまな単語があります。その後、foreachループを呼び出して“$MySentence”文字列の各単語を印刷します。foreachループは、文字列から繰り返される単語を保持する“MyWords”オブジェクトで設定されています。その後、doとdoneのステートメントの間に配備されたechoコマンドを使って、文字列から繰り返された単語を出力します。
#!/usr/bin/env bash
MySentence="Bash is an effective programming"
for MyWords in $MySentence
do
echo "$MyWords"
done「Ctrl+Alt+T」のショートカットキーでターミナルを開き、Bashコマンドを使って「bash.sh」ファイルをコンパイルします。シェルに表示される単語は、スペース、タブ、改行がBashのフィールド区切りと見なされるため、別の行に表示されます。
bash ./Bash.sh例2: $IFS演算子を使用したBashスクリプト
指定された文字列で単語を分ける際に、$IFS演算子を使用せずに行います。必要な文字を使用して$IFS演算子を適用することもできます。デフォルトのIFSを変更する場合は、古い値を変数に保存しておくことが賢明です。必要なタスクが完了したら、元の文字をIFSに再割り当てすることができます。$IFS演算子を用いて単語を分けるBashスクリプトを見てみましょう。
ここでは、「Persons」変数の中でコロン「:」で区切られた人物の名前として文字列を指定します。その後、元のIFS値を「Pre_ifs」属性に保存します。次に、コロン「:」を区切り文字として設定したIFS変数を宣言します。このIFS変数は、forループに使用される単語トークンとして使用されます。foreachループを使用して、「Persons」変数の分割された文字列を走査し、すべての文字列要素をfor-eachループの「Per」オブジェクトに渡します。その後、doとdoneコマンドの中でecho文を使用して、区切られた文字列を表示します。
#/bin/bash
Persons=Alex:Thomas:Kyle:Jenny
Pre_ifs="$IFS"
IFS=":"
for Per in $Persons
do
echo The name of Persons are $Per
doneターミナルでBashスクリプトファイルを使ってコンパイルし、IFSオペレーターの出力を確認してください。IFSオペレーターのBashファイルが実行されると、次のフォーマットで各文字列が分割されます。
例3:ファイルからユーザー名を表示するための$IFSオペレーターを使用したBashスクリプト
今、私たちはBashスクリプトで$IFSオペレーターを使用して、“/etc/passwd”ファイルからユーザーの名前を表示します。ここで使用する$IFSオペレーターは、シェル内の各ユーザー名を区切ります。以下のBashスクリプトは、“IFS”変数の宣言から始まり、“$’\n’”文字とコロン“:”で設定されます。$’\n’文字は改行文字であり、エスケープシーケンスとして使用されます。ユーザー名は指定されたIFSによって区切られます。
この後、値が「1」に設定された変数「x」があります。そして、catコマンドを使用して「/etc/passwd」ファイルを参照し、foreachループの「user」オブジェクトにユーザー名を渡して「/etc/passwd」ファイルのすべてのユーザーを反復処理します。「do」と「done」コマンドは、ユーザーを出力するためにネストされた「if」条件文に指定されています。
IFS=$'\n':x=1
for user in `cat /etc/passwd`
do
if [ $x -eq 1 ]
then
echo $user
fi
if [ $x -eq 7 ]
then
x=1
else
x=$((x+1))
fi
done次の端末画面でBashスクリプトを実行し、指定されたフィールド区切り文字によって「/etc/passwd」のユーザーを出力します:
例4:$IFSを使用したコマンドラインBashスクリプト
IFSは特定のシェル変数であるため、コマンドラインで直接使用できます。ここでは、IFSオペレーターを使用するためのショートカットがあります。別のBashスクリプトファイルを作成する代わりに、ターミナルを開いて"IFS"変数を定義します。"IFS"変数はハイフン"-"区切り文字で設定されます。それから、フィールド区切り文字ハイフン"-"で区切られた"Hello-Geeks"文字列をエコーします。その後、readコマンドを使用して変数"var1"と"var2"を定義し、これらの変数を別々にエコーします。
IFS="-"
echo "Hello-Geeks!" | (read var1 var2; echo $var1; echo $var2)出力は「Hello」文字列と「Geeks」文字列を別々に取得します。したがって、$IFSは区切り文字を個別に受け入れます。
例5: IFSを使用したBashスクリプトでのユーザー定義文字列の分割
前のBashスクリプトでは、機能を示すために$IFS演算子を利用しました。今、IFS演算子を使用して、ユーザーがターミナルで定義した単語の文字列の区切り文字を設定します。-pフラグを使ったreadコマンドを与えます。このコマンドは「スペースを含む文字列を入力してください」という文を表示します。その後、入力された文字列は「StringIs」変数に初期化されます。IFS演算子は、文字列を分割するためのスペース区切りで設定されます。
次に、“read -ra ADDR” コマンドがあります。これは、“$StrinIS” をIFSによって分割されたトークンの配列として読み取ります。“-r”オプションは、バックスラッシュ“\”がエスケープ文字ではなく文字であることを指定します。“-a”オプションは、単語が0から始まる配列の連続インデックスに割り当てられた$IFSによって区切られることを指定します。その後、foreachループを通じて配列の文字列要素にアクセスします。
#!/bin/bash
read -p "Enter the string with space: " StringIS
IFS=' '
read -ra ADDR <<<"$StringIS"
for i in "${ADDR[@]}";
do
echo "$i"
doneユーザーが入力した文字列には、次のように取得される空白があります:
結論
この社説では、Bashスクリプトを実装することで、$IFSを使用してトークンを分離する方法を発見しました。また、コマンドプロンプトでも$IFSを使用して文字列を分割しました。これは、文字列の分離を達成する非常にシンプルで短い方法です。ただし、シェルは各IFS文字を区切り文字として使用し、他の反復の結果を単語に分割します。




