bashシェルスクリプトで、tsv形式(タブ区切り)のファイルを読み込む方法を解説します。
はじめに
本記事では、tsv形式(タブ区切り)のファイルを読み込む方法を説明します。
読み込む方法として、下記の2つの方法を説明したいと思います。
また、ファイル内の文字列にスペースが含まれている場合の読み込み方も記載しています。
- 区切り文字(IFS)を変更する方法
- 区切り文字(IFS)を変更しない方法
普通にファイルを読み込んだ場合
まず、区切り文字を変更せずに読み込むとどうなるかを確認してみます。
例として、以下のようなファイルを読み込みます。
あいうえお か き く け こ さしすせそ た ち つ て と なにぬねの は ひ ふ へ ほ
以下のように記述することで、ファイルを読み込むことが出来ます。
#!/bin/bash
for str in $(cat ./data/file1.txt)
do
echo ${str}
done
タブとスペースが改行として扱われるため、以下のような結果になります。
[root@STKPUB002 workspace]# sh test.sh あいうえお か き く け こ さしすせそ た ち つ て と なにぬねの は ひ ふ へ ほ
区切り文字(IFS)を変更する方法
ここでは、システムの区切り文字(IFS)が設定されている環境変数の値を変更して、tsv形式のファイルを読み込む方法を説明します。
for文を使用して読み込む
区切り文字(IFS)を変更して読み込む方法です。
3行目のように、IFSを「\n」(改行)のみにして、for文で1行ずつ読み込みます。
その後、7行目で、IFSを「\t」(タブ)にして、カラムごとに配列に格納しています。
#!/bin/bash
IFS=$'\n'
for line in $(cat ./data/file1.txt)
do
IFS=$'\t'
count=$((${count} + 1))
array=(${line//\t/ })
echo 【${count}行目】カラム1:${array[0]}
echo 【${count}行目】カラム2:${array[1]}
done
上記の実行結果です。
tsv形式のファイルが正しく読み込まれていることが分かります。
[root@STKPUB002 workspace]# sh test.sh 【1行目】カラム1:あいうえお 【1行目】カラム2:か き く け こ 【2行目】カラム1:さしすせそ 【2行目】カラム2:た ち つ て と 【3行目】カラム1:なにぬねの 【3行目】カラム2:は ひ ふ へ ほ
while read文を使用して読み込む
for文を使用した方法では、IFSを2度変更しましたが、
while readを使用することで、1度だけの変更でよくなります。
#!/bin/bash
IFS=$'\t'
cat ./data/file1.txt | while read line
do
count=$((${count} + 1))
array=(${line/// })
echo 【${count}行目】カラム1:${array[0]}
echo 【${count}行目】カラム2:${array[1]}
done
上記の実行結果です。
[root@STKPUB002 workspace]# sh test.sh 【1行目】カラム1:あいうえお 【1行目】カラム2:か き く け こ 【2行目】カラム1:さしすせそ 【2行目】カラム2:た ち つ て と 【3行目】カラム1:なにぬねの 【3行目】カラム2:は ひ ふ へ ほ
IFSの設定を変更→戻す方法
シェルスクリプト内で、IFSを変更し、処理終了後に元に戻す方法を説明します。
#!/bin/bash
# IFSのバックアップ
IFSORG=$IFS
# IFSを変更
IFS=$'\t'
# 処理
echo 処理実行
# IFSを戻す
IFS=$IFSORG
区切り文字(IFS)を変更しない方法
ここでは、システムの区切り文字(IFS)を変更せずに、tsv形式のファイルを読み込む方法を説明します。
文字列に半角スペースを含む場合、まずは別の文字(今回は★マーク)に置き換えます。
その後、while readで1行ずつ取得、タブで分割して配列に格納しています。
最後に、置き換えた文字を半角スペースに戻します。
#!/bin/bash
cat ./data/file1.txt | while read line
do
count=$((${count} + 1))
array=(${line//" "/"★"})
echo 【${count}行目】カラム1:${array[0]}
echo 【${count}行目】カラム2:`echo ${array[1]} | sed -e "s/★/ /g"`
done
上記の実行結果です。
IFSを変更せずに、tsv形式のファイルを読み込むことが出来ました。
[root@STKPUB002 workspace]# sh test.sh 【1行目】カラム1:あいうえお 【1行目】カラム2:か き く け こ 【2行目】カラム1:さしすせそ 【2行目】カラム2:た ち つ て と 【3行目】カラム1:なにぬねの 【3行目】カラム2:は ひ ふ へ ほ
コメント