シェルスクリプトの基礎 - IFS

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

環境変数IFS(Internal Filed Separator)には、bashの場合、スペース、タブ、改行($' \t\n')が初期設定されており、
これらが区切り文字(デリミタ)として認識されている。

ファイル等を読み込む場合、文字列の区切り文字を変更するには、IFSに区切り文字とする値を設定することができる。

例えば、csvファイルを読み込む場合は、IFSにカンマ(,)を設定する。

現在のIFSの確認するには、以下のコマンドを実行する。

echo $IFS | od -ac



区切り文字を設定

区切り文字の設定例として、/etc/passwdファイルからユーザ名とログインシェルの情報を抜き出して表示させる。
この場合、/etc/passwdファイルの各フィールドの区切り文字はコロン(:)である。

まず、IFSを設定せずに内容を抜き出せるか確認する。
実行すると、初期設定では区切り文字にコロン(:)は設定されていないため、1行が全て変数USERに格納される。

 #!/bin/bash
 
 head -n 5 /etc/passwd | while read USER PASS USERID GROUPID COMMENT HOMEDIR LOGINSHELL
 do
    echo "$USER $LOGINSHELL"
 done


# 出力
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin


次に、IFSに:を設定して確認する。

まず、現在のIFSの設定を変数OLDIFSでバックアップした後、IFSにコロン(:)を設定する。
更に、/etc/passwdファイルの各フィールドを、それぞれ変数USER、PASS、USERID、GROUPID、COMMENT、HOMEDIR、LOGINSHELLに格納して、
ユーザ名とログインシェルを抜き出して表示する。
最後に、変数OLDIFSを使用してIFSの設定を元に戻す。

 #!/bin/bash
 
 OLDIFS=$IFS
 IFS=:
 
 head -n 5 /etc/passwd | while read USER PASS USERID GROUPID COMMENT HOMEDIR LOGINSHELL
 do
    echo "$NAME $LOGINSHELL"
 done
 
 IFS=$OLDIFS


# 出力
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin



空白やタブを含む文字列を扱う

空白やタブなどを区切り文字にしない場合は、IFSの値を空にすることで、空白やタブで区切ることなく読み込むことができる。

以下のシェルスクリプトでは、空白を含むlist.txtファイルを使用して確認する。

# list.txtファイルの内容
a b c
d e f
g i j


まず、IFSを初期設定のままで実行する。
IFSの初期設定は、空白、タブ、改行となっているため、空白で区切られた文字が1文字ずつ変数iに格納されて、1文字ずつ表示する。

 #!/bin/bash
 
 for i in $(cat ./list.txt)
 do
    echo $i
 done


# 出力
a
b
c
d
e
f
g
i
j


次に、IFSの値を空に設定して実行する。
区切り文字として空白が設定されていないため、1列全部が変数iに格納されて、1行ずつ表示する。

 #!/bin/bash
 
 OLDIFS=$IFS
 IFS=
 
 for i in $(cat ./list.txt)
 do
    echo $i
 done
 
 IFS=$OLDIFS


# 出力
a b c
d e f
g i j