根据分隔符将一个文件拆分为多个文件

use*_*178 70 unix linux awk split

我有一个文件-|在每个部分后都带有分隔符...需要使用unix为每个部分创建单独的文件.

输入文件的示例

wertretr
ewretrtret
1212132323
000232
-|
ereteertetet
232434234
erewesdfsfsfs
0234342343
-|
jdhg3875jdfsgfd
sjdhfdbfjds
347674657435
-|
Run Code Online (Sandbox Code Playgroud)

文件1中的预期结果

wertretr
ewretrtret
1212132323
000232
-|
Run Code Online (Sandbox Code Playgroud)

文件2中的预期结果

ereteertetet
232434234
erewesdfsfsfs
0234342343
-|
Run Code Online (Sandbox Code Playgroud)

文件3中的预期结果

jdhg3875jdfsgfd
sjdhfdbfjds
347674657435
-|
Run Code Online (Sandbox Code Playgroud)

ctr*_*lor 82

一个班轮,没有编程.(正则表达式除外)

csplit --digits=2  --quiet --prefix=outfile infile "/-|/+1" "{*}"
Run Code Online (Sandbox Code Playgroud)

  • @ zb226我做了很长时间,所以不需要解释. (30认同)
  • 对于OS X用户,请注意操作系统附带的csplit版本不起作用.你需要coreutils中的版本(可以通过Homebrew安装),这个版本叫做*gcsplit*. (8认同)
  • 对于那些想知道参数意味着什么的人:`--digits = 2`控制用于对输出文件进行编号的数字位数(2对我来说是默认的,所以没必要).`--quiet`抑制输出(这里也没有必要或要求).`--prefix`指定输出文件的前缀(默认为xx).所以你可以跳过所有参数,并获得像`xx12`这样的输出文件. (6认同)
  • 我建议添加`--elide-empty-files`,否则最后会有一个空文件. (5认同)
  • 只需添加一下,即可获得OS X的版本(至少在High Sierra上可用)。您只需要稍微调整args`csplit -k -f = outfile infile“ /-\ | / + 1”“ {3}”`。似乎不起作用的功能是““ {*}”`,我必须具体说明分隔符的数量,并且需要添加-k以避免在找不到文件时删除所有输出文件的情况。最后的分隔符。另外,如果要使用“ --digits”,则需要使用“ -n”。 (3认同)

Wil*_*ell 34

awk '{print $0 " -|"> "file" NR}' RS='-\\|'  input-file
Run Code Online (Sandbox Code Playgroud)

解释(编辑):

RS是记录分隔符,此解决方案使用gnu awk扩展名,允许它是多个字符.NR是记录号码.

print语句打印一条记录,然后打印" -|"到包含其名称中的记录号的文件中.

  • 对我来说,它在31.728s中分割了3.3 GB (2认同)
  • @ccf文件名只是`>`右侧的字符串,所以你可以随意构建它.例如,`print $ 0" - |" >"file"NR".txt"` (2认同)

twa*_*erg 7

Debian有csplit,但我不知道这对所有/大多数/其他发行版是否共同.如果没有,那么追踪源代码并编译它应该不会太难......

  • 由于[`csplit`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/csplit.html)在POSIX中,我希望它基本上可用于所有类Unix系统. (3认同)

Joh*_*ith 5

我解决了一个稍微不同的问题,其中文件包含一个带有名称的行,其中后面的文本应该去.这个perl代码对我有用:

#!/path/to/perl -w

#comment the line below for UNIX systems
use Win32::Clipboard;

# Get command line flags

#print ($#ARGV, "\n");
if($#ARGV == 0) {
    print STDERR "usage: ncsplit.pl --mff -- filename.txt [...] \n\nNote that no space is allowed between the '--' and the related parameter.\n\nThe mff is found on a line followed by a filename.  All of the contents of filename.txt are written to that file until another mff is found.\n";
    exit;
}

# this package sets the ARGV count variable to -1;

use Getopt::Long;
my $mff = "";
GetOptions('mff' => \$mff);

# set a default $mff variable
if ($mff eq "") {$mff = "-#-"};
print ("using file switch=", $mff, "\n\n");

while($_ = shift @ARGV) {
    if(-f "$_") {
    push @filelist, $_;
    } 
}

# Could be more than one file name on the command line, 
# but this version throws away the subsequent ones.

$readfile = $filelist[0];

open SOURCEFILE, "<$readfile" or die "File not found...\n\n";
#print SOURCEFILE;

while (<SOURCEFILE>) {
  /^$mff (.*$)/o;
    $outname = $1;
#   print $outname;
#   print "right is: $1 \n";

if (/^$mff /) {

    open OUTFILE, ">$outname" ;
    print "opened $outname\n";
    }
    else {print OUTFILE "$_"};
  }
Run Code Online (Sandbox Code Playgroud)