シェルスクリプトの基礎 - IFS
概要
環境変数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