![](https://seccdn.libravatar.org/avatar/cade75bc5a38eae7b8d86692a7433a68.jpg?s=120&d=mm&r=g)
On Thursday 14 July 2005 11:05, Jens Gruentjes wrote:
Hallo Liste,
ich suche seit einiger Zeit nach einer Möglichkeit, Teile aus einer Binärdatei herauszuschneiden. Ich hatte gehofft, das ginge mit cut oder mit dd, aber leider hat das bei mir nicht funktioniert.
Die Datensaätze in den Binärdateien, um die es geht, haben alle eine feste Länge, sagen wir mal 8700 Bytes. Der gesamte Datenbestand umfasst 38000 Sätze, so dass die Datei insgesamt 330.600.000 Bytes groß ist. Ich möchte jetzt aus dieser Datei die Bytes 1 bis 1000, 3000 bis 3500 und 8500 bis 8700 ausschneiden und damit einen neuen Datensatz mit der Länge 1700 Bytes erzeugen. Die gesamte Datei hätte dann die Größe 64.600.000 Bytes.
Wie kann ich so etwas machen?
Mit Perl ist es ein Einzeiler: perl -ne 'BEGIN{$/=\8700;} print substr( $_, 0, 1000 ), substr( $_, 3000, 500 ), substr( $_, 8500, 200 );' <input >output Ich habe das Ganze etwas vereinfacht getestet: perl -e 'for( 1..10 ) {$i=0;print( map( {chr($_+ ++$i)} (0x20)x87 ) );}' | perl -ne 'BEGIN{$/=\87;} print substr( $_, 0, 10 ), substr( $_, 30, 5 ), substr( $_, 85, 2 ), "\n";' Das erste Perl-Kommando erzeugt 10x die ersten 87 ASCII Zeichen nach dem Blank, der zweite Perl-Aufruf schneidet aus jedem Record, der 87 Bytes lang ist, die Zeichen 1-10, 30-35 und 85-87 heraus. Das Newline am Ende des print-Statements ist nur zur besseren Übersicht. Es geht aber vielleicht auch mit der bash: perl -e 'for( 1..10 ) {$i=0;print( map( {chr($_+ ++$i)} (0x20)x85 ), "\n\n" );}' | (IFS=;while read -n 10 -d '' a && read -n 20 -d '' dummy && read -n 5 -d '' b && read -n 50 -d '' dummy && read -n 2 -d '' c; do echo -n $a$b$c; done) Das Perl-Kommando erzeugt wieder 87 Bytes lange Records, die die Subshell mit read liest. Zum Test habe ich in die Records auch Newlines eingebettet. Mit IFS='' und -d '' stören sie nicht. Ich nehme aber an, dass es durchaus "böse" Zeichen gibt, mit denen read vorzeitig abbricht, z.B. '\0'. Torsten