#navi(../)
* スペースが含まれる文字列を1行として扱う方法 [#e175fc16]
#contents
一行単位でデータを扱いたいが、シェルの区切り文字がスペースになっていて変更できないかなぁ?と思っている方は、本記事が役に立つと思います。~
尚、使用したシェルはbashになります。
以下のようなデータファイルがあり、スペース区切りで1行に3つの項目が格納されているファイルを利用して説明します。
#ref(data.txt)
$ cat data.txt
Fedora Debian Ubuntu
Vine Plamo CentOS
openSUSE KNOPPIX Slackware
#htmlinsertpcsp(linux_ads_top.html,linux-sp.html)
* スペース区切りになっている為、項目毎の表示となる [#n637a230]
シェルの区切り文字を変更しないと以下のように、項目毎表示されてしまいます。~
#ref(test1.sh)
#!/bin/bash
i=0
for L in `cat data.txt`
do
i=`expr $i + 1`
echo $i : $L
done
-上記シェルの実行結果
$ ./test.sh
1 : Fedora
2 : Debian
3 : Ubuntu
4 : Vine
5 : Plamo
6 : CentOS
7 : openSUSE
8 : KNOPPIX
9 : Slackware
本当は3行として出力を期待しているのだが、区切り文字がスペース(改行含む)のため、9項目として処理されてしまう。
* IFSを変更して区切り文字を改行だけにする [#y44021bd]
IFS(''I''nternal ''F''ield ''S''eparator )に区切り文字を設定することにより解決できます。~
以下にサンプルスクリプトを記します。
#ref(test2.sh)
#!/bin/bash
IFS_BACKUP=$IFS
IFS=$'\n'
i=0
for L in `cat data.txt`
do
i=`expr $i + 1`
echo $i : $L
done
IFS=$IFS_BACKUP
上記のIFS_BACKUPに変更前の区切り文字設定をバックアップしIFS環境変数を改行のみ指定します。~
処理終了後、IFS_BACKUP変数を使用しIFS環境変数の設定を元に戻しています。
-上記シェルの実行結果
$ ./test2.sh
1 : Fedora Debian Ubuntu
2 : Vine Plamo CentOS
3 : openSUSE KNOPPIX Slackware
** $'\n'以外の書き方 [#h2c08afb]
以下の2つは同じ意味になります。
IFS=$'\n'
IFS ='
'
上記は直接改行を入力した状態です。
#ref(test3.sh)
#!/bin/bash
IFS_BACKUP=$IFS
IFS='
'
i=0
for L in `cat data.txt`
do
i=`expr $i + 1`
echo $i : $L
done
IFS=$IFS_BACKUP
* 改行区切り文字と他の区切り文字の混在 [#i1048c22]
以下のテストデータを利用し改行の他に他の区切り文字も設定してみます。
#ref(data2.txt)
$ cat data2.txt
Fedora,Debian,Ubuntu
Vine#Plamo#CentOS
openSUSE&KNOPPIX&Slackware
区切り文字を、改行、#、, 、&の4つとした場合は以下のIFS設定になります。
#ref(test4.sh)
#!/bin/bash
IFS_BACKUP=$IFS
IFS='
,&#'
i=0
for L in `cat data2.txt`
do
i=`expr $i + 1`
echo $i : $L
done
IFS=$IFS_BACKUP
-上記シェルの実行結果
$ ./test4.sh
1 : Fedora
2 : Debian
3 : Ubuntu
4 : Vine
5 : Plamo
6 : CentOS
7 : openSUSE
8 : KNOPPIX
9 : Slackware
1行に複数の項目がある場合、IFSの変更により区切り文字を変更することができるため、データの扱いが便利になります。~
1行として扱いたいと思う事が多いと思います。~
上記のサンプルによりIFSを改行だけと設定すれば簡単にデータを取り扱う事ができます。~
また、区切り文字を複数にする方法も記述しました。~
最後にIFSのバックアップは必ず取るようにし、区切り文字の変更が必要な場所のみで使用し、その後、バックアップからIFSを元にもどしましょう。~
そうしないと、意図しない動作になるかもしれませんので。
#htmlinsertpcsp(linux_ads_btm.html,linux-sp.html)