[英]Splitting all txt files in a folder into smaller files based on a regular expression using bash
[英]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.