Anzeige:
Ergebnis 1 bis 5 von 5

Thema: Aus Dateien was "rausschneiden"

  1. #1
    Janine123
    Gast

    Aus Dateien was "rausschneiden"

    Hallo Jungs,

    ich hab z.B. eine "configfile"

    mit dem Inhalt:

    [ü1]
    abc=1
    bac=2
    cba=3
    [ü2]
    abc=2
    bac=1
    cba=3
    [ü3]
    ...
    ...
    ...

    So also dieses File ist in Abschnitte mit Überschriften unterteilt die immer mit "[]"

    gekennzeichnet sind und ich möchte jetzt wissen wie ich aus der ganzen Datei

    immer nur einen Abschnitt z.B. den Abschnitt "[ü1]" mit allen Werten darunter bis Abschnitt [ü2] rausschneide und in einem anderen File abspeicher kann so das es in dem anderen File nur das gäbe...

    [ü1]
    abc=1
    bac=2
    cba=3

    Achja und die Überschriften in den [] müssten variablen sein.

  2. #2
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Variante 1 mit awk:
    Code:
    jan@jack:~/tmp/fcut> cat get_sect.awk
    BEGIN { print_it = 0;
            sect     = ""; }
    $1 ~ /^\[.+\]$/ { sect = substr($1, 2, length($1) - 2);
                     if (sect == par_sect)
                        print_it = 1;
                     else
                        print_it = 0; }
    { if (print_it == 1) print $0; }
    jan@jack:~/tmp/fcut> awk -f get_sect.awk -v par_sect=ü2 config.txt
    [ü2]
    abc=2
    bac=1
    cba=3
    Variante 2 mit Perl:
    Code:
    jan@jack:~/tmp/fcut> cat get_sect.pl
    #! /usr/bin/perl
    
    use strict;
    use warnings;
    
    die "usage: get_sect.pl section\n" unless defined $ARGV[0];
    my $par_sect = $ARGV[0];
    
    my $print_it = 0;
    my $sect     = "";
    while (<STDIN>) {
      if (/^\[.+\]$/) {
        ($sect) = $_ =~ m/^\[(.+)\]$/;
        if ($sect eq $par_sect) {
          $print_it = 1;
        }
        else {
          $print_it = 0;
        }
      }
      print $_ if $print_it == 1;
    }
    exit 0;
    jan@jack:~/tmp/fcut> ./get_sect.pl ü2 <config.txt
    [ü2]
    abc=2
    bac=1
    cba=3
    Jan

  3. #3
    Registrierter Benutzer
    Registriert seit
    05.02.2006
    Beiträge
    116
    Dafür kann man auch Config::IniFiles verwenden...

  4. #4
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von reneeb Beitrag anzeigen
    Dafür kann man auch Config::IniFiles verwenden...
    Ja, kann man und ist auch sicher besser, wenn man mit den Einträgen weiterarbeiten will. Für diesen einfachen Fall erspart das nicht viel Arbeit (man muss parsen, suchen und die Ausgabe wieder zusammenbauen):
    Code:
    #! /usr/bin/perl
    
    use strict;
    use warnings;
    use Config::IniFiles;
    
    die "usage: get_sect.pl file section\n" unless defined $ARGV[0] && defined $ARGV[1];
    my $cfg = new Config::IniFiles( -file => $ARGV[0]);
    my $par_sect = $ARGV[1];
    if (!$cfg->SectionExists($par_sect)) {
      die "section $par_sect does not exist in ini file";
    }
    
    print "[", $par_sect, "]\n";
    my @params = $cfg->Parameters($par_sect);
    foreach (@params) {
      print $_, "=", $cfg->val($par_sect, $_), "\n";
    }
    exit 0;
    Jan

  5. #5
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Ein anderer Gesichtspunkt, ob und wann man Perl-Module anstatt selbstgeschriebener Routinen verwenden sollte, fiel mir später ein - das Thema hat offensichtlich in meinem Kopf noch rumgespukt :

    Ich habe mir mal eine (zugegebenermaßen übertrieben große) Ini-Datei wie folgt gebastelt:
    Code:
    for i in `seq 1 10000`; do
      echo "[sect$i]" >>config.ini
      for k in `seq 1 10`; do
        echo "par$k=$i$k" >>config.ini
      done
    done
    (daraus wurden ca. 1,2 MB) und dann beide Varianten mal laufen lassen (get_sect.pl ist die handgestrickte Variante, get_sect2.pl diejenige, die Config::IniFiles benutzt):
    Code:
    jan@jack:~/tmp/fcut> time ./get_sect.pl sect5000 <config.ini >config_teil.ini
    
    real    0m0.116s
    user    0m0.094s
    sys     0m0.003s
    jan@jack:~/tmp/fcut> time ./get_sect2.pl config.ini sect5000 >config_teil2.ini
    
    real    1m16.293s
    user    1m16.145s
    sys     0m0.079s
    Bei einer config.ini mit 1.000 statt 10.000 Sektionen (110 KB) sah es immer noch so aus:
    Code:
    jan@jack:~/tmp/fcut> time ./get_sect.pl sect500 <config.ini >config_teil.ini
    
    real    0m0.021s
    user    0m0.018s
    sys     0m0.004s
    jan@jack:~/tmp/fcut> time ./get_sect2.pl config.ini sect500 >config_teil2.ini
    
    real    0m1.094s
    user    0m1.083s
    sys     0m0.010s
    Der Ini-Parser liest offensichtlich erst die gesamte Datei ein, parst sie und stellt erst dann die Ergebnisse bereit. Einer der Prozessoren war in dieser Zeit mit 100% ausgelastet. Man sollte also meiner Meinung nach - wenn keine Notwendigkeit besteht, die Datei zu validieren oder die Ergebnisse weiterzuverwenden - lieber mal die Arme-Leute-Version (selbstgebastelt) nehmen - das spart unter Umständen viel Zeit, auch bei kleineren Ini-Files, wenn man oft drübergehen muss.

    Jan

    P.S.: awk ist noch nen Tick schneller:
    Code:
    jan@jack:~/tmp/fcut> time awk -f get_sect.awk -v par_sect=sect500 config.ini >config_teil3.ini
    
    real    0m0.016s
    user    0m0.014s
    sys     0m0.001s
    Geändert von jan61 (04-09-2007 um 00:20 Uhr) Grund: awk ist noch schneller

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •