如同生物信息领域中的FASTA/Q格式一样,CSV/TSV作为计算机、数据科学和生物信息的基本格式,应用非常广泛。常用的处理软件包括:

  1. 以微软Excel为代表的电子表格软件
  2. Notepad++/SublimeText等文本编辑器
  3. sed/awk/cut等Shell命令
  4. 各种编程语言的数据处理库。

然而,电子表格软件和文本编辑器固然强大,但依赖鼠标操作,不适合批量处理;sed/awk/cut等Shell命令主要用于通用的表格数据,不适合含有标题行的CSV格式为了一个小操作写Python/R脚本也有点小题大作,且难以复用

开发csvtk前现有的工具主要是Python写的csvkit,Rust写的xsv,C语言写的miller,都各有优劣。当时我刚开发完seqkit,投文章过程中时间充足,便想趁热再造一个轮子。

所以我决定写一个命令行工具来满足CSV/TSV格式的常见操作,这就是csvtk了。

介绍

基本信息

特性

功能

在开发csvtk之前的两三年间,我已经写了几个可以复用的Python/Perl脚本(https://github.com/shenwei356/datakit) ,包括csv2tab、csvtk_grep、csv_join、csv_melt,intersection,unique。所以我的计划是首先集成这些已有的功能,随后根据需求进行扩展。

到目前为止,csvtk已有27个子命令,分为以下几大类:

使用

  1. 输入数据要求每行的列数一致,空行也会报错
  2. csvtk默认输入数据含有标题行,如没有请开启全局参数-H
  3. csvtk默认输入数据为CSV格式,如为TSV请开启全局参数-t
  4. 输入数据列名最好唯一无重复
  5. 如果TSV中存在双引号"",请开启全局参数-l
  6. csvtk默认以#开始的为注释行,若标题行含#,请给全局参数-C指定另一个不常见的字符(如$

例子

仅提供少量例子,更多例子请看使用手册 http://bioinf.shenwei.me/csvtk/usage/ 。

  1. 示例数据

    $ cat names.csv
    id,first_name,last_name,username
    11,"Rob","Pike",rob
    2,Ken,Thompson,ken
    4,"Robert","Griesemer","gri"
    1,"Robert","Thompson","abc"
    NA,"Robert","Abel","123"
    
  2. 增强可读性

    $ cat names.csv  | csvtk pretty
    id   first_name   last_name   username
    11   Rob          Pike        rob
    2    Ken          Thompson    ken
    4    Robert       Griesemer   gri
    1    Robert       Thompson    abc
    NA   Robert       Abel        123
    
  3. 转为markdown

    $ cat names.csv | csvtk csv2md
    id |first_name|last_name|username
    :--|:---------|:--------|:-------
    11 |Rob       |Pike     |rob
    2  |Ken       |Thompson |ken
    4  |Robert    |Griesemer|gri
    1  |Robert    |Thompson |abc
    NA |Robert    |Abel     |123
    

    效果

    id first_name last_name username
    11 Rob Pike rob
    2 Ken Thompson ken
    4 Robert Griesemer gri
    1 Robert Thompson abc
    NA Robert Abel 123
  4. 用列或列名来选择指定列,可改变列的顺序

    $ cat names.csv | csvtk cut -f 3,1          | csvtk pretty
    $ cat names.csv | csvtk cut -f last_name,id | csvtk pretty
    last_name   id
    Pike        11
    Thompson    2
    Griesemer   4
    Thompson    1
    Abel        NA
    
  5. 用通配符选择多列

    $ cat names.csv | csvtk cut -F -f '*name,id' | csvtk pretty
    first_name   last_name   username   id
    Rob          Pike        rob        11
    Ken          Thompson    ken        2
    Robert       Griesemer   gri        4
    Robert       Thompson    abc        1
    Robert       Abel        123        NA
    
  6. 删除第2,3列(下列第二种方法是选定范围,但-3在前,-2在后

    $ cat names.csv | csvtk cut -f -2,-3                  | csvtk pretty
    $ cat names.csv | csvtk cut -f -3--2                  | csvtk pretty
    $ cat names.csv | csvtk cut -f -first_name,-last_name | csvtk pretty
    id   username
    11   rob
    2    ken
    4    gri
    1    abc
    NA   123
    
  7. 按指定列搜索,默认精确匹配

    $ cat names.csv | csvtk grep -f id -p 1 | csvtk pretty
    id   first_name   last_name   username
    1    Robert       Thompson    abc
    
  8. 模糊搜索(正则表达式)

    $ cat names.csv | csvtk grep -f id -p 1 -r | csvtk pretty
    id   first_name   last_name   username
    11   Rob          Pike        rob
    1    Robert       Thompson    abc
    
  9. 用文件作为模式来源

    $ cat names.csv | csvtk grep -f id -P id-files.txt
    
  10. 对指定列做简单替换

    $ cat names.csv | csvtk replace -f id -p '(\d+)' -r 'ID: $1' | csvtk pretty
    id       first_name   last_name   username
    ID: 11   Rob          Pike        rob
    ID: 2    Ken          Thompson    ken
    ID: 4    Robert       Griesemer   gri
    ID: 1    Robert       Thompson    abc
    NA       Robert       Abel        123
    
  11. 用key-value文件来替换(seqkit和brename都支持类似操作)

    $ cat data.tsv
    name    id
    A       ID001
    B       ID002
    C       ID004
    
    $ cat alias.tsv
    001     Tom
    002     Bob
    003     Jim
    
    $ csvtk replace -t -f 2 -p "ID(.+)" -r "N: {nr}, alias: {kv}" -k alias.tsv data.tsv
    name    id
    A       N: 1, alias: Tom
    B       N: 2, alias: Bob
    C       N: 3, alias: 004
    
  12. 合并表格,需要分别指定各文件中的key列:默认均为第一列;若列(名)相同提供一个;若不同用分号分割

    $ cat testdata/phones.csv
    username,phone
    gri,11111
    rob,12345
    ken,22222
    shenwei,999999
    
    $ csvtk join -f 'username;username' --keep-unmatched names.csv phones.csv | csvtk pretty
    id   first_name   last_name   username   phone
    11   Rob          Pike        rob        12345
    2    Ken          Thompson    ken        22222
    4    Robert       Griesemer   gri        11111
    1    Robert       Thompson    abc
    NA   Robert       Abel        123