【问题标题】:Make a file look not messed up使文件看起来没有混乱
【发布时间】:2020-02-25 13:48:09
【问题描述】:

我有一个看起来很乱的文件:

contig_1  bin.0013 Rhizobium           flavum    (taxid 1335061)
contig_2           Alphaproteobacteria (taxid    28211)
contig_3  bin.009
contig_4  bin.008  unclassified        (taxid    0)
contig_5  bin.001  Fluviicoccus        keumensis (taxid 1435465)
contig_12 bin.003

我希望它与制表符分隔的列和空的零看起来正确:

contig_1    bin.0013    Rhizobium flavum (taxid 1335061)
contig_2    0           Alphaproteobacteria (taxid 28211)
contig_3    bin.009     0
contig_4    bin.008     unclassified (taxid 0)
contig_5    bin.001     Fluviicoccus keumensis (taxid 1435465)
contig_12   bin.003     0

如果我使用 sed 's/ /,/g' filename 之类的东西,除了 1-2 和 2-3 列之外的任何地方都插入逗号。

【问题讨论】:

  • 尝试column 命令
  • 我试过了,还是没有解决问题。
  • 这并不像你想象的那么简单。查看您的第一个文件,我假设应该有 5 个字段(config_1bin.0013Rhizobiumflavum(tax id ...))。然而事实证明只有 3 个。
  • 是的,这来自输入文件,其名称类似于 Rhizobium flavum (taxid 1335061) 和空格。虽然我希望应该有办法

标签: bash delimiter


【解决方案1】:

如果awk 是您的选择,请尝试以下方法:

awk -v OFS="\t" '
NR==FNR {
    # in the 1st pass, detect the starting positions of the 2nd field and the 3rd
    sub(" +$", "")      # it avoids misdetection due to extra trailing blanks
    if (match($0, "[^[:blank:]]+[[:blank:]]+")) {
        # RLENGTH holds the ending position of the 1st blank
        if (col2 == 0 || RLENGTH < col2) col2 = RLENGTH + 1
        if (match($0, "[^[:blank:]]+[[:blank:]]+[^[:blank:]]+[[:blank:]]+")) {
            # RLENGTH holds the ending position of the 2nd blank
            if (col3 == 0 || RLENGTH < col3) col3 = RLENGTH + 1
        }
    }
    next
}
{
    # in the 2nd pass, extract the substrings in the fixed position and reformat them
    # by removing extra spaces and putting "0" if the fiels is empty
    c1 = substr($0, 1, col2 - 1); sub(" +$", "", c1); if (c1 == "") c1 = "0"
    c2 = substr($0, col2, col3 - col2); sub(" +$", "", c2); if (c2 == "") c2 = "0"
    c3 = substr($0, col3); gsub(" +", " ", c3); if (c3 == "") c3 = "0"
#   print c1, c2, c3            # use this for the tab-separated output
    printf("%-12s%-12s%-s\n", c1, c2, c3)
}' file file

输出:

contig_1    bin.0013    Rhizobium flavum (taxid 1335061)
contig_2    0           Alphaproteobacteria (taxid 28211)
contig_3    bin.009     0
contig_4    bin.008     unclassified (taxid 0)
contig_5    bin.001     Fluviicoccus keumensis (taxid 1435465)
contig_12   bin.003     0
  • 该过程由两个通道组成。在第 1 遍中,它会检测字段的起始位置。
  • 在第 2 遍中,它使用第 1 遍中计算的位置剪切各个字段。
  • 我选择了printf 来直观地对齐输出。你可以切换到tab separated values 取决于偏好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多