【问题标题】:Splitting multiple files together将多个文件拆分在一起
【发布时间】:2014-05-02 22:10:42
【问题描述】:

我有 70 个文件,看起来像 (file1 = complex.1.txt;... file69 = complex.69.txt... file70 = complex.70.txt)

ATOM   7066  O   GLY A 784      49.130  43.743 -23.586  1.00  1.00           O  
nnn
CONECT  337  403 
END
ATOM      1  N   ARG B   1      26.564 -17.621   9.457  1.00  1.00           N1+
ATOM      2  CA  ARG B   1      26.733 -18.764   8.526  1.00  1.00           C  

我想将所有 70 个文件分成两部分。第二个文件将在 END 之后开始。所有文件的拆分文件名将是 complex.1.txt_part1 和 complex.1.txt_part2 等等。 我尝试了awk解决方案

for ((i=1;i<=70;i++)); do awk '{file="complex.1.txt_part"++k;printf "%s%s",$0,RS > file;close(file)}' RS='END\n' complex.$i.txt; done

但它只给出 2 个文件的结果。有人可以纠正这个或发布其他好的解决方案。

【问题讨论】:

    标签: perl bash shell unix awk


    【解决方案1】:

    gawk 具有 FILENAME 内置变量,这可能对您的要求有用。这个单线应该可以完成这项工作:

    awk 'FNR==1{f=0}{print > FILENAME (f?"_part2":"_part1")}/END/{f=1}' complext.*.txt
    

    【讨论】:

      【解决方案2】:

      这是一个 Perl 单行解决方案:

      perl -n0e '$k=1; for (split /(?<=^END\n)/m) { open $fh, ">complex.$..txt_part".$k++; print $fh $_ }' complex.*.txt
      

      说明

      它使用这两个特殊的命令行选项:

      -n
      ...告诉 Perl 逐条读取给定的输入文件,并为每条记录运行指定的单行。默认情况下,一条记录是一行,但是...
      -0
      ...告诉 Perl 将“空字节”而不是“换行符”作为输入记录分隔符,因此整个文件将计为一条记录。


      然后在单行代码本身:

      • split /(?&lt;=^END\n)/m

        ...将输入记录分成两个字符串,使用look-behind assertion 匹配行首的字符串END,后跟换行符。

      • for (...) { ... }

        ...确保对两个拆分字符串中的每一个分别完成正确的部分

      • open $fh, "&gt;..."; print $fh $_

        ...打开一个新文件进行写入,然后将当前分割字符串写入其中

      • $.

        ...引用当前输入记录号的特殊变量(即,每读取一条记录,它就会自动加一)。

      • $k=1; ... $k++

        ...这样输出文件将在for 循环的第一次迭代中以“_part1”结尾,但在第二次迭代中以“_part2”结尾,对于每个输入记录。

      【讨论】:

      • 嗯,所以看起来虽然 stackoverflow allows dl/dd/dt 标签,它没有为它们提供合适的样式?太糟糕了...
      猜你喜欢
      • 1970-01-01
      • 2016-07-26
      • 2021-03-04
      • 1970-01-01
      • 2017-08-24
      • 2013-08-24
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多