it-swarm.com.de

Aufteilen einer großen Textdatei in jede leere Zeile

Ich habe ein bisschen Probleme beim Aufteilen einer großen Textdatei in mehrere kleinere. Die Syntax meiner Textdatei lautet wie folgt:

dasdas #42319 blaablaa 50 50
content content
more content
content conclusion

asdasd #92012 blaablaa 30 70
content again
more of it
content conclusion

asdasd #299 yadayada 60 40
content
content
contend done
...and so on

(dasdas # 42319 blaablaa 50 50, content content, more content & content schlussfolgerung sind alle ihre eigenen separaten zeilen, gefolgt von einer leeren zeile am ende dieser informationstabelle. eine typische informationstabelle in meiner datei hat irgendwo zwischen 10-40 zeilen. )

Ich würde diese Datei in n kleinere Dateien aufteilen, wobei n die Menge der Inhaltstabellen ist.
Das ist

dasdas #42319 blaablaa 50 50
content content
more content
content conclusion

wäre eine eigene separate Datei (whateverN.txt)

und

asdasd #92012 blaablaa 30 70
content again
more of it
content conclusion

nochmal eine separate datei whateverN + 1.txt und so weiter.

Es scheint, als ob awk oder Perl ein geschicktes Werkzeug dafür sind, aber sie noch nie zuvor verwendet zu haben, ist irgendwie verwirrend.

Ich habe diese beiden Fragen gefunden, die fast meinem Problem entsprechen, konnte aber die Syntax nicht an meine Bedürfnisse anpassen.

Textdatei in mehrere Dateien aufteilen &
https://unix.stackexchange.com/questions/46325/how-can-i-split-a-text-file-into-multiple-text-files

Wie soll man die Kommandozeilen-Eingaben ändern, damit es mein Problem löst?

12
tropical e

Wenn Sie RS auf null setzen, wird awk angewiesen, eine oder mehrere Leerzeilen als Datensatztrennzeichen zu verwenden. Dann können Sie einfach NR verwenden, um den Namen der Datei festzulegen, die jedem neuen Datensatz entspricht:

 awk -v RS= '{print > ("whatever-" NR ".txt")}' file.txt

RS: Dies ist awks Input Record Separator. Der Standardwert ist eine Zeichenfolge, die ein einzelnes Zeilenumbruchzeichen enthält. Dies bedeutet, dass ein Eingabedatensatz aus einer einzelnen Textzeile besteht. Dies kann auch die Nullzeichenfolge sein. In diesem Fall werden Datensätze durch Leerzeilen getrennt. oder ein regulärer Ausdruck. In diesem Fall werden Datensätze durch Übereinstimmungen mit dem regulären Ausdruck im Eingabetext getrennt.

$ cat file.txt
dasdas #42319 blaablaa 50 50
content content
more content
content conclusion

asdasd #92012 blaablaa 30 70
content again
more of it
content conclusion

asdasd #299 yadayada 60 40
content
content
contend done

$ awk -v RS= '{print > ("whatever-" NR ".txt")}' file.txt

$ ls whatever-*.txt
whatever-1.txt  whatever-2.txt  whatever-3.txt

$ cat whatever-1.txt 
dasdas #42319 blaablaa 50 50
content content
more content
content conclusion

$ cat whatever-2.txt 
asdasd #92012 blaablaa 30 70
content again
more of it
content conclusion

$ cat whatever-3.txt 
asdasd #299 yadayada 60 40
content
content
contend done
$ 
20
jas

Perl hat eine nützliche Funktion, die als Trennzeichen für Eingabedatensätze bezeichnet wird. $/.

Dies ist die Markierung zum Trennen von Datensätzen beim Lesen einer Datei.

So:

#!/usr/bin/env Perl
use strict;
use warnings;

local $/ = "\n\n"; 
my $count = 0; 

while ( my $chunk = <> ) {
    open ( my $output, '>', "filename_".$count++ ) or die $!;
    print {$output} $chunk;
    close ( $output ); 
}

Genau so. Der <> ist insofern das 'magische' Dateihandle, als er weitergeleitete Daten oder Dateien liest, die in der Befehlszeile angegeben sind (öffnet und liest sie). Dies ähnelt der Funktionsweise von sed oder grep.

Dies kann zu einem Einzeiler reduziert werden:

Perl -00 -pe 'open ( $out, '>', "filename_".++$n ); select $out;'  yourfilename_here
3
Sobrique

Sie können diese awk verwenden,

awk 'BEGIN{file="content"++i".txt"} !NF{file="content"++i".txt";next} {print > file}' yourfile

(ODER)

awk 'BEGIN{i++} !NF{++i;next} {print > "filename"i".txt"}' yourfile

Mehr lesbares Format:

BEGIN {
        file="content"++i".txt"
}
!NF {
        file="content"++i".txt";
        next
}
{
        print > file
}
2
sat

Falls Sie die Fehlermeldung "zu viele offene Dateien" erhalten, gehen Sie wie folgt vor ...

awk: whatever-18.txt makes too many open files
 input record number 18, file file.txt
 source line number 1

Möglicherweise müssen Sie die neu erstellte Datei wie folgt schließen, bevor Sie eine neue erstellen können.

awk -v RS= '{close("whatever-" i ".txt"); i++}{print > ("whatever-" i ".txt")}' file.txt
1
KuldeepSinh

Da es Freitag ist und ich mich ein bisschen hilfsbereit fühle ... :)

Versuche dies. Wenn die Datei so klein ist, wie Sie meinen, ist es am einfachsten, sie alle auf einmal zu lesen und im Speicher zu arbeiten.

use strict;
use warnings;

# Slurp file
local $/ = undef;
open my $fh, '<', 'test.txt' or die $!;
my $text = <$fh>;
close $fh;

# split on double new line
my @chunks = split(/\n\n/, $text);

# make new files from chunks
my $count = 1;
for my $chunk (@chunks) {
    open my $ofh, '>', "whatever$count.txt" or die $!;
    print $ofh $chunk, "\n";
    close $ofh;
    $count++;
}

In den Perl-Dokumenten können einzelne Befehle erläutert werden, die Sie nicht verstehen. An dieser Stelle sollten Sie sich jedoch wahrscheinlich auch ein Tutorial ansehen.

0
Nick P

Versuchen Sie auch dieses Bash-Skript

#!/bin/bash
i=1
fileName="OutputFile_$i"
while read line ; do 
if [ "$line"  == ""  ] ; then
 ((++i))
 fileName="OutputFile_$i"
else
 echo $line >> "$fileName"
fi
done < InputFile.txt
0
Kalanidhi
awk -v RS="\n\n" '{for (i=1;i<=NR;i++); print > i-1}' file.txt

Legt das Datensatztrennzeichen als Leerzeile fest und druckt jeden Datensatz als separate Datei mit den Nummern 1, 2, 3 usw. Die letzte Datei endet (nur) in einer Leerzeile.

0
user2138595