簡體   English   中英

使用 BASH 中的 shell 腳本在正則表達式上將一個大的 txt 文件拆分為 200 個較小的 txt 文件

[英]Splitting a large txt file into 200 smaller txt files on a regex using shell script in BASH

我希望這個主題足夠清楚,我在之前詢問的 bin 中沒有找到任何關於此的具體內容。 我試過用 Perl 或 Python 實現它,但我想我可能太努力了。

是否有一個簡單的 shell 命令/管道可以根據開始和結束的正則表達式將我的 4mb .txt 文件拆分為單獨的 .txt 文件?

我在下面提供了文件的簡短示例.. 這樣您就可以看到每個“故事”都以短語“X of XXX DOCUMENTS”開頭,可用於拆分文件。

我認為這應該很容易,如果 bash 不能做到這一點,我會感到驚訝 - 比 Perl/Py 快。

這是:

                           1 of 999 DOCUMENTS


              Copyright 2011 Virginian-Pilot Companies LLC
                          All Rights Reserved
                   The Virginian-Pilot(Norfolk, VA.)

...



                           3 of 999 DOCUMENTS


                  Copyright 2011 Canwest News Service
                          All Rights Reserved
                          Canwest News Service

...

在此先感謝您的幫助。

羅斯

awk '/[0-9]+ of [0-9]+ DOCUMENTS/{g++} { print $0 > g".txt"}' file

OSX 用戶將需要gawk ,因為內置的awk會產生類似awk: illegal statement at source line 1的錯誤

紅寶石(1.9+)

#!/usr/bin/env ruby
g=1
f=File.open(g.to_s + ".txt","w")
open("file").each do |line|
  if line[/\d+ of \d+ DOCUMENTS/]
    f.close
    g+=1
    f=File.open(g.to_s + ".txt","w")
  end
  f.print line
end

正如其他解決方案中所建議的,您可以使用csplit

csplit csplit.test '/^\.\.\./' '{*}' && sed -i '/^\.\.\./d' xx*

我還沒有找到更好的方法來擺脫拆分文件中的回憶分隔符。

你在 Perl 上有多努力?

編輯這是一種更快的方法。 它拆分文件然后打印零件文件。

use strict;
use warnings;

my $count = 1;

open (my $file, '<', 'source.txt') or die "Can't open source.txt: $!";

for (split /(?=^.*\d+[^\S\n]*of[^\S\n]*\d+[^\S\n]*DOCUMENTS)/m, join('',<$file>))
{
    if ( s/^.*(\d+)\s*of\s*\d+\s*DOCUMENTS.*(\n|$)//m )
    {
        open (my $part, '>', "Part$1_$count.txt") 
            or die "Can't open Part$1_$count for output: $!";
        print $part $_;
        close ($part);
        $count++;
    }
}
close ($file);

這是逐行方法:

use strict;
use warnings;

open (my $masterfile, '<', 'yourfilename.txt') or die "Can't open yourfilename.txt: $!";

my $count = 1;
my $fh;

while (<$masterfile>) {
    if ( /(?<!\d)(\d+)\s*of\s*\d+\s*DOCUMENTS/ ) {
        defined $fh and close ($fh);
        open ($fh, '>', "Part$1_$count.txt") or die "Can't open Part$1_$count for  output: $!";
        $count++;
        next;
    }
    defined $fh and print $fh $_;
}
defined $fh and close ($fh);
close ($masterfile);

匹配“X of XXX DOCUMENTS”的正則表達式是
\\d{1,3} 的 \\d{1,3) 文檔

逐行讀取並在正則表達式匹配時開始寫入新文件應該沒問題。

未經測試:

base=outputfile
start=1
pattern='^[[:blank:]]*[[:digit:]]+ OF [[:digit:]]+ DOCUMENTS[[:blank:]]*$

while read -r line
do
    if [[ $line =~ $pattern ]]
    then
        ((start++))
        printf -v filecount '%4d' $start
        >"$base$filecount"    # create an empty file named like foo0001
    fi
    echo "$line" >> "$base$filecount"
done

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM