#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)

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS