【问题标题】:Splitting one file into multiple files将一个文件拆分为多个文件
【发布时间】:2014-04-26 21:31:17
【问题描述】:

我有一个像下面这样的大文件,我想把这个文件分成多个文件。每个文件都应该在 ENDMDL 之后中断。对于以下文件,将有三个名为pose1.av、pose2.av和pose3.av的输出文件。

MODEL        1
SML    170  O   PRO A  17      16.893   3.030   0.799  1.00  1.00           O
SML    171  OXT PRO A  17      18.167   2.722   2.597  1.00  1.00           O
TER     172      PRO A  17
ENDMDL
MODEL        2
SML      4  CG  ARG A   1      -2.171  -7.105  -4.278  1.00  1.00           C
SML      5  CD  ARG A   1      -1.851  -8.581  -4.022  1.00  1.00           C
SML    113  HD1 HIS A  12       2.465  -8.206   5.062  1.00  1.00           H
TER     114      HIS A  12
ENDMDL
MODEL        3
SML    101  N   HIS A  12       3.765  -3.995   7.233  1.00  1.00           N
SML    102  CA  HIS A  12       2.584  -4.736   6.934  1.00  1.00           C
TER     103      HIS A  12
ENDMDL

【问题讨论】:

    标签: perl bash shell sed


    【解决方案1】:

    一个相当有效的方法,使用 bash 和 sed:

    n=0
    while IFS= read -r firstline; do
        { echo "$firstline"; sed '/^ENDMDL$/q'; } > "pose$((++n)).av"
    done < file
    

    它比其他 Bash 答案效率更高:输出文件只打开一次,并且大部分解析是由 sed 完成的,而不是 bash。

    【讨论】:

    • 不错!我了解这些命令是如何工作的,但是sed 是如何接收任何输入的?
    • @JoshJolly 它刚刚从标准输入读取! read 从 stdin 和 sed 读取一行,直到 ENDMDL 等等......文件 file 被馈送到整个 while 块的 stdin。
    【解决方案2】:

    csplit 可以开箱即用

    csplit -z -s -f pose -b "%01d.av" file '/^ENDMDL$/+1' '{*}'
    

    【讨论】:

      【解决方案3】:

      Awk 是这个任务的不错选择:

      awk '{file="pose"++i;printf "%s%s",$0,RS > file;close(file)}' RS='ENDMDL\n' file
      

      【讨论】:

      • 这需要是gnu awk,因为记录选择器中有多个字符。
      【解决方案4】:

      使用 perl 单行代码

      perl -ne '$fh or open $fh, "> pose".++$i".av"; print $fh $_; undef $fh if /^ENDMDL/' file.txt
      

      【讨论】:

        【解决方案5】:

        在纯 Bash 中:

        cnt=1
        while read line; do
            echo "$line" >> pose${cnt}.av
            [ "$line" == "ENDMDL" ] && let cnt+=1
        done < filename.txt
        

        【讨论】:

        • 使用[ ... = ... ] (POSIX) 或[[ ... == ... ]][ ... == ... ] 不符合标准,一些shell 会卡住它。
        【解决方案6】:
        awk '/^MODEL/{out="pose"++cnt".av"} {print > out}' file
        

        【讨论】:

          猜你喜欢
          • 2016-07-26
          • 2013-08-24
          • 2021-03-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多