次の形式のファイルがあり、タブで区切られています
a k testis adult male 8 week rRNA
b k testis adult male 8 week rRNA
c k testis adult male 8 week rRNA
各行でなんらかの操作を実行したいので、whileループを使用しています。タブで各行を分割してから、6番目の列である8 week
変数内。このコードを使用していますが、必要なものを取得できません
while read -r line; do tmp=(${line///}); col6=${tmp[5]}; echo "$col6"; done < file.txt
これは8
ではなく8 week
。 8週間は8と週の間にスペースがあるので、タブで行を分割したいと思います。
配列の割り当てtmp=(${line///})
は、IFS
に含まれるすべての文字の値を分割します。これには、デフォルトでタブ、およびスペースおよび改行が含まれます。 (空の置換が何をするのかわかりません。)タブでのみ分割するには、IFS
を次のように設定します。
foo=$'a\tk\testis\tadult\tmale\t8 week\tRNA'
IFS=$'\t'
tmp=($foo)
echo "${tmp[5]}"
それでもグロビングは問題として残っていますが、すでにwhile read
を使用しているため、read -a tmp
(少なくともBashでは)を使用できますが、IFS
に基づいて入力行を分割します。そして、フィールドを名前付き配列の要素に分離します:
$ while IFS=$'\t' read -r -a tmp ; do
echo "${tmp[5]}"
done <<< $'a\tk\testis\tadult\tmale\t8 week\tRNA'
これは8 week
を出力します。これのもう1つの利点は、IFS
の変更がread
の期間中のみ有効であり、スクリプトの残りの部分では有効でないことです。
もちろん、フィールドの数/意味がわかっている場合は、read
を分割して名前付き変数を分離することができます。
... IFS=$'\t' read -r col1 col2 col3 ...
または、その1列だけを印刷する場合は、cut
を使用します。
cut -d$'\t' -f 6 < file.txt