タブで区切られた次の形式のファイルがあります。
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と週の間にスペースがあるので、タブで行を分割したいと思います。
答え1
配列の割り当ては、デフォルトでタブを含む含まれるすべての文字tmp=(${line///})
に値を分割します。IFS
そして空間改行文字。 (空の置換が何であるかわかりません。)タブでのみ分割するには、次のように設定しますIFS
。
foo=$'a\tk\testis\tadult\tmale\t8 week\tRNA'
IFS=$'\t'
tmp=($foo)
echo "${tmp[5]}"
それでもワイルドカードが問題になり、すでに使用しているので、これに基づいて入力行を分割し、結果フィールドを次のように保存する(Bashでのみksh / zsh / yashに置き換えます)をwhile read
使用できます。名前付き配列:read -a tmp
-a
-A
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
タブを区切り文字として使用すると、空のフィールドが削除されます。では、交換することで、このようなことが発生するのを防ぐzsh
ことができます。IFS=$'\t'
IFS=$'\t\t'
もちろん、フィールドの数/意味を知っていれば、read
それを別の名前付き変数に分割できます。
... IFS=$'\t' read -r col1 col2 col3 ...
または、この列のみを印刷するには、次を使用しますcut
。
cut -d$'\t' -f 6 < file.txt
空の列があり、cut -d$'\t'
別のIFS=$'\t'
動作をする場合。 Cut は、個々のタブをそれぞれ異なる区切り文字として扱い、read
連続タブを 1 つの区切り文字として扱います。一つスプリッタ。つまり、文字列はfoo<tab><tab>bar
2つの列として読み取られますread
が、3つの列では読み取られませんcut
。
タブの設定は変更できませんが、印刷文字は常に別の区切り文字として認識されるため、データに表示されない一部の文字でタブを変更してから、左右の区切り... | tr '\t' : | IFS=: read -r -a tmp
記号として使用できます。