我有一个以下格式的文件,它是制表符分隔的
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
为:虽然这仍然是一个问题,并且由于您已经在使用
while read
,您可以使用read -a tmp
(仅在 Bash 中,用 ksh/zsh/yash 替换-a
)-A
,它基于 拆分输入行IFS
,并将结果字段存储为命名数组:打印出来
8 week
。这样做的另一个好处是,更改IFS
仅在 的持续时间内有效,read
对脚本的其余部分无效。但是请注意,
read
使用制表符作为分隔符时会删除空字段。在zsh
中,您可以替换IFS=$'\t'
为IFS=$'\t\t'
以阻止这种情况发生。当然,如果我们知道字段的数量/含义,我们可以
read
将它们拆分为单独的命名变量:或者,如果您只想打印那一列,请使用
cut
:如果您有空列,
cut -d$'\t'
并且IFS=$'\t'
对它们有不同的行为。Cut 会将每个单独的选项卡视为不同的分隔符,而read
将连续的选项卡视为单个分隔符。也就是说,字符串foo<tab><tab>bar
将被读取为两列 byread
,但三列 bycut
。您无法为制表符更改此设置,但打印字符始终被识别为不同的分隔符,因此您可以将制表符更改为未出现在数据中的某个字符,然后将其用作分隔符,例如
... | tr '\t' : | IFS=: read -r -a tmp
左右。