简体   繁体   English

一起分割多个文件

[英]Splitting multiple files together

I have 70 files that looks like (file1 = complex.1.txt;... file69 = complex.69.txt... file70 = complex.70.txt) 我有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  

I want to break all 70 files in two parts. 我想将所有70个文件分成两个部分。 The second file will start after END. 第二个文件将在END之后开始。 The splitted file name will be complex.1.txt_part1 and complex.1.txt_part2 and so on for all files. 对于所有文件,分割后的文件名将分别为complex.1.txt_part1和complex.1.txt_part2,依此类推。 I tried the awk solution 我尝试了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

but it gives only 2 files in result. 但结果只有2个文件。 Could someone correct this or post the other nice solutions. 有人可以纠正这个问题还是发布其他不错的解决方案。

gawk has FILENAME built-in variable, which could be useful for your requirement. gawk具有FILENAME内置变量,可能对您的需求有用。 This one-liner should do the job: 此一线工作:

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

Here's a Perl one-liner solution: 这是一个Perl一线解决方案:

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

Explanation 说明

It uses these two special command line-options: 它使用以下两个特殊的命令行选项:

-n
...tells Perl to read the given input files record-by-record, and run the specified one-liner for each record. ...告诉Perl逐条记录读取给定的输入文件,并为每条记录运行指定的单行代码。 By default a record is one line, but... 默认情况下,一条记录为一行,但是...
-0
...tells Perl to treat the "null byte" rather than "newline" as the input record separator, so a whole file will count as one record. ...告诉Perl将“空字节”而不是“换行符”作为输入记录分隔符,因此整个文件将被视为一条记录。


Then in the one-liner code itself: 然后在单行代码本身中:

  • split /(?<=^END\\n)/m

    ...splits the input record into two strings, using a look-behind assertion which matches the string END at the beginning of a line and followed by a newline. ...使用后向断言将输入记录分为两个字符串,该断言在行的开头与字符串END相匹配,后跟换行。

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

    ...makes sure that the right part is done separately for each of the two split strings ...确保为两个分割字符串分别完成正确的部分

  • open $fh, ">..."; print $fh $_

    ...opens a new file for writing, and then writes the current split string to it ...打开一个新文件进行写入,然后将当前的拆分字符串写入其中

  • $.

    ...special variable that refers to the current input record number (ie it is automatically incremented by one for each record that is read). ...引用当前输入记录编号的特殊变量(即,对于每个读取的记录,它会自动加一)。

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

    ...this is so the output file will end with "_part1" on the the first iteration of the for loop, but "_part2" on the second iteration, for each input record. ...这样,对于每个输入记录,输出文件将在for循环的第一次迭代中以“ _part1”结尾,而在第二次迭代中以“ _part2”结尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM