【问题标题】:How to reformat file with sed/vim?如何使用 sed/vim 重新格式化文件?
【发布时间】:2019-04-10 09:13:45
【问题描述】:

我有一个像这样的.csv 文件。

atomnum,atominfo,metric
238,A-30-CYS-SG,53.7723
889,A-115-CYS-SG,46.2914
724,A-94-CYS-SG,44.6405
48,A-6-CYS-SG,37.2108
630,A-80-CYS-SG,29.574
513,A-64-CYS-SG,23.1925
981,A-127-CYS-SG,19.8903
325,A-41-GLN-OE1,17.6205
601,A-76-CYS-SG,17.5079

我想这样改:

atomnum,atominfo,metric
238,C30-SG,53.7723
889,C115-SG,46.2914
724,C94-SG,44.6405
48,C6-SG,37.2108
630,C80-SG,29.574
513,C64-SG,23.1925
981,C127-SG,19.8903
325,Q41-OE1,17.6205
601,C76-SG,17.5079

逗号之间的部分是原子标识符:其中 A-30-CYS-SG 是 A 链中残基 30 的 γ 硫,它是一个半胱氨酸。残基可以用三个字母或一个 (表在这里https://www.iupac.org/publications/pac-2007/1972/pdf/3104x0639.pdf)。基本上,我只想a)将三个字母代码更改为一个字母代码,b)删除链ID(在本例中为A)和c)将残基编号放在一个字母代码旁边。

我已经尝试匹配 vim 中逗号之间的模式。像s%:\(-\d\+\-\)\(\u\+\):\2\1:g 这样的东西给了我c),即(ACYS-30--SG)。我不知道怎么做 a) 用 vim。我知道如何使用 sed 和一个包含所有替代命令的输入文件来做到这一点。但是,使用 sed 完成所有工作可能会更好......我在问是否有可能在 vim 上做 a)?

谢谢

【问题讨论】:

  • 如果你不描述具体的变化是什么,人们不得不根据输入和输出进行猜测。此外,如果您展示您的尝试以及失败的原因,您的问题可能会更好地被接受。

标签: csv vim sed


【解决方案1】:

使用sedpastecutbash,给定输入atoms.csv

paste -d, <(cut -d, -f1 atoms.csv) \
          <(cut -d, -f2 atoms.csv | sed 's/.-//
                                         s/\(.*\)-\([A-Z]\{3\}\)-/\2\1-/
                                         s/^ALA/A/
                                         s/^ARG/R/
                                         s/^ASN/N/
                                         s/^ASP/D/
                                         s/^CYS/C/
                                         s/^GLU/E/
                                         s/^GLN/Q/
                                         s/^GLY/G/
                                         s/^HIS/H/
                                         s/^ILE/I/
                                         s/^LEU/L/
                                         s/^LYS/K/
                                         s/^MET/M/
                                         s/^PHE/F/
                                         s/^PRO/P/
                                         s/^SER/S/
                                         s/^THR/T/
                                         s/^TRP/W/
                                         s/^TYR/Y/
                                         s/^VAL/V/') \
          <(cut -d, -f3 atoms.csv)

输出:

atomnum,atominfo,metric
238,C30-SG,53.7723
889,C115-SG,46.2914
724,C94-SG,44.6405
48,C6-SG,37.2108
630,C80-SG,29.574
513,C64-SG,23.1925
981,C127-SG,19.8903
325,Q41-OE1,17.6205
601,C76-SG,17.5079

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -r '1b;s/$/\n:ALAA:ARGR:ASNN:ASPD:CYSC:GLUE:GLNQ:GLYG:HISH:ILEI:LEUL:LYSK:METM:PHEF:PROP:SERS:THRT:TRPW:TYRY:VALV/;s/,A-([0-9]+)-(...)(.*)\n.*:\2(.).*/,\4\1\3/' file
    

    在每一行附加一个查找表,并使用模式匹配将 3 个字母的代码(和整数值)替换为 1 个字母的代码。查找键是一个冒号,后跟 3 个字母的键,然后是 1 个字母的代码。

    【讨论】:

    • 输出的第 2 行是查找表本身,它与规范不同。固定...
    • 有效,只是查找键随机出现在输出中。
    • @murpholinox 如果查找表随机出现在输出中,则表明查找表不完整,并且有一个或多个键未计算在内。
    【解决方案3】:

    如果您知道如何在 sed 中执行此操作,为什么不利用这些知识并直接从 Vim 中调用?

    :%!sed -e '<your sed script>'
    

    一旦你完成了它并且它工作了,你就可以在 Vim 函数中弹出它。

    functioni Transform()
        your sed command
    endfunction
    

    然后就使用

    :call Transform()
    

    你可以映射到一个键。

    简单!

    【讨论】:

    • 很高兴知道这一点。我实际上是用 sed 做的,但刚才我不小心删除了输入文件。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 2012-01-11
    • 2018-12-17
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    相关资源
    最近更新 更多