Bash中以制表符分隔的表的列编辑和重命名

时间:2018-10-18 16:00:06

标签: bash shell terminal

为基本问题表示歉意,但我感到非常困惑。我有一个基本的制表符分隔的文本文件,名为map.txt。文件的第一行是列名,其后跟#字符。注意,这是一个制表符分隔的文件。这是head map.txt的输出:

#SampleID   BarcodeSequence LinkerPrimerSequence    sample_type Description geneticSampleID
OSBS.087.39.M.32.18.20140227    TCCCTTGTCTCC    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A1   OSBS_087-M-32-18-20140227-gen
OSBS.048.41.M.37.33.20140227    ACGAGACTGATT    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A2   OSBS_048-M-37-33-20140227-gen
OSBS.048.23.M.15.31.20140227    GCTGTACGGATT    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A3   OSBS_048-M-15-31-20140227-gen
OSBS.047.21.M.20.3.20140227 ATCACCAGGTGT    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A4   OSBS_047-M-20-3-20140227-gen
OSBS.119.23.M.18.38.20140227    TGGTCAACGATA    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A5   OSBS_119-M-18-38-20140227-gen
OSBS.047.41.M.22.36.20140227    ATCGCACAGTAA    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A6   OSBS_047-M-22-36-20140227-gen
OSBS.087.41.M.40.21.20140227    GTCGTGTAGCCT    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A7   OSBS_087-M-40-21-20140227-gen
OSBS.048.21.M.5.11.20140227 AGCGGAGGTTAG    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A8   OSBS_048-M-5-11-20140227-gen
OSBS.119.39.M.27.5.20140227 ATCCTTTGGTTC    CGGCTGCGTTCTTCATCGATGC  soil    Plate 1A9   OSBS_119-M-27-5-20140227-gen

我想将名称geneticSampleID更改为Name,将名称BarcodeSequence更改为Index1。然后,我想删除除新命名的NameIndex1列以外的所有列。我希望文件的第一行保留列名NameIndex1,并以#字符开头。在vim中更改列的名称非常简单,而删除列则不是。

所需的输出:

#Index1 Name 
TCCCTTGTCTCC OSBS_087-M-32-18-20140227-gen
ACGAGACTGATT OSBS_048-M-37-33-20140227-gen
GCTGTACGGATT OSBS_048-M-15-31-20140227-gen
ATCACCAGGTGT OSBS_047-M-20-3-20140227-gen
TGGTCAACGATA OSBS_119-M-18-38-20140227-gen
ATCGCACAGTAA OSBS_047-M-22-36-20140227-gen
GTCGTGTAGCCT OSBS_087-M-40-21-20140227-gen
AGCGGAGGTTAG OSBS_048-M-5-11-20140227-gen
ATCCTTTGGTTC OSBS_119-M-27-5-20140227-gen

3 个答案:

答案 0 :(得分:2)

cut -f2,6 inputfile | sed '1{ s/geneticSampleID/Name/; s/BarcodeSequence/Index1/; s/^/#/; }'
  1. 剪切仅过滤第2列和第6列
  2. Sed将genericSampleId替换为名称s/.../.../,将BarcodeSeuqnce替换为索引,但仅替换了第一行1{ .. }
  3. 也sed添加了#个字符s/^/#/
  4. 有一天我会学习awk!

可通过onlinegdb获得实时版本。

答案 1 :(得分:1)

您可以使用awksed之类的shell命令来执行此操作,例如:

cat map.txt | awk '{ print $2, $7}' | sed 's/BarcodeSequence/#Index1 Name/'

输出:

#Index1 Name 
TCCCTTGTCTCC OSBS_087-M-32-18-20140227-gen
ACGAGACTGATT OSBS_048-M-37-33-20140227-gen
GCTGTACGGATT OSBS_048-M-15-31-20140227-gen
ATCACCAGGTGT OSBS_047-M-20-3-20140227-gen
TGGTCAACGATA OSBS_119-M-18-38-20140227-gen
ATCGCACAGTAA OSBS_047-M-22-36-20140227-gen
GTCGTGTAGCCT OSBS_087-M-40-21-20140227-gen
AGCGGAGGTTAG OSBS_048-M-5-11-20140227-gen
ATCCTTTGGTTC OSBS_119-M-27-5-20140227-gen

尽管现在我们正在使用sed用2个新名称替换1个列名称,但是这对我来说很不客气。因此,在这种情况下,我更喜欢仅使用awk的方式:

awk 'BEGIN{ print "#Name", "Index1"} NR>1 { print $2, $7}' map.txt

答案 2 :(得分:1)

您可以像这样使用单个awk

awk 'BEGIN{FS=OFS="\t"; print "Index1", "Name"} NR>1{print $2, $6}' file

Code Demo

输出:

Index1  Name
TCCCTTGTCTCC    OSBS_087-M-32-18-20140227-gen
ACGAGACTGATT    OSBS_048-M-37-33-20140227-gen
GCTGTACGGATT    OSBS_048-M-15-31-20140227-gen
ATCACCAGGTGT    OSBS_047-M-20-3-20140227-gen
TGGTCAACGATA    OSBS_119-M-18-38-20140227-gen
ATCGCACAGTAA    OSBS_047-M-22-36-20140227-gen
GTCGTGTAGCCT    OSBS_087-M-40-21-20140227-gen
AGCGGAGGTTAG    OSBS_048-M-5-11-20140227-gen
ATCCTTTGGTTC    OSBS_119-M-27-5-20140227-gen