Anzeige:
Ergebnis 1 bis 10 von 10

Thema: awk: field separator im string

  1. #1
    Registrierter Benutzer Avatar von moedule
    Registriert seit
    04.10.2003
    Beiträge
    346

    awk: field separator im string

    hey

    ich hab hier einen recht großen datensatz (190 MB) den ich gerne mit awk zerlegen möchte. das problem ist, dass der mit komma separierte datensatz einige strings enthält, die ebenfalls kommas enthalten können. diese sind mit " gekennzeichnet

    wie bringe ich dem awk bei, diese kommas als field separator zu ignorieren?

    danke für eure hilfe
    moe
    Geändert von moedule (25-05-2006 um 16:13 Uhr)

  2. #2
    Registrierter Benutzer Avatar von SeeksTheMoon
    Registriert seit
    22.02.2002
    Beiträge
    762
    Wie? Ein " vor dem Komma, oder zwei drum herum oder der ganze String mit " umgeben?
    I haven't lost my mind - It's somewhere on a backup-disc

  3. #3
    Registrierter Benutzer Avatar von moedule
    Registriert seit
    04.10.2003
    Beiträge
    346
    drum herum, also ungefähr sowas.

    126, "bla bla", 545, "hund, katze, maus", 6764, "blub"

    feld1 = 126
    feld2 = "bla bla"
    feld3=545
    feld4 = "hund, katze, maus"
    feld5 = 6764
    feld6="blub"

    jeder string ist von zwei " eingeschlossen

    awk liefert die falsche anzahl an feldern, er zählt die kommas im string mit.

    hab schon versucht mit sed die kommas im string zu ersetzen, stell mich da aber zu blöd an (es werden zum beispiel auch die kommas zwischen zwei nicht zusammengehörigen " ersetzt)

    moe

  4. #4
    Registrierter Benutzer Avatar von Romanday
    Registriert seit
    03.02.2004
    Beiträge
    829
    Zitat Zitat von moedule
    hab schon versucht mit sed die kommas im string zu ersetzen, stell mich da aber zu blöd an (es werden zum beispiel auch die kommas zwischen zwei nicht zusammengehörigen " ersetzt)

    moe
    Alles vorher in ein Array einlesen.
    mit match suchen, danach ersetzen + ausgeben.
    Ist aber ein wenig hackselig.

    Ich glaube du kommst mit einer anderen Scriptsprache
    (Perl etc.) schneller zum Ziel.
    Abriss, bzw. die Sprengung des World Trade Centers
    WDR Dokumentation
    Doku + DT Untertitel
    Weitere Infos - Terrorstorm

  5. #5
    Registrierter Benutzer Avatar von moedule
    Registriert seit
    04.10.2003
    Beiträge
    346
    Zitat Zitat von Romanday
    Alles vorher in ein Array einlesen.
    mit match suchen, danach ersetzen + ausgeben.
    Ist aber ein wenig hackselig.

    Ich glaube du kommst mit einer anderen Scriptsprache
    (Perl etc.) schneller zum Ziel.
    würde ich ja machen, z.B. erstmal die kommas im string ändern ... ic blicks mit den ganzen regexp nicht :-(

    moe

  6. #6
    Registrierter Benutzer Avatar von Romanday
    Registriert seit
    03.02.2004
    Beiträge
    829
    Zitat Zitat von moedule
    würde ich ja machen, z.B. erstmal die kommas im string ändern ... ic blicks mit den ganzen regexp nicht :-(

    moe
    1x umrühren, dann geht es:

    PHP-Code:
    <?function n($n){$n=str_replace(',','',$n[1]);return '"'.$n.'"';}?>
    <?=preg_replace_callback('/\"([^\"]+)\"/'"n"$d)?>
    Geändert von Romanday (27-05-2006 um 20:08 Uhr)
    Abriss, bzw. die Sprengung des World Trade Centers
    WDR Dokumentation
    Doku + DT Untertitel
    Weitere Infos - Terrorstorm

  7. #7
    Registrierter Benutzer Avatar von moedule
    Registriert seit
    04.10.2003
    Beiträge
    346
    danke für deine mühe!
    ich hab auch ne awk-lösung:

    das stichwort für google lautet: "the csv problem" und vielleicht awk. leider find ich die seite gerade nicht mehr woher ich dann die funktionierende lösung hatte ..
    aber das hier sollte es irgendwie auch tun

    http://groups.google.com/group/comp....73d9e784c68dee

    moe

  8. #8
    Registrierter Benutzer Avatar von Romanday
    Registriert seit
    03.02.2004
    Beiträge
    829
    Zitat Zitat von moedule
    danke für deine mühe!
    ich hab auch ne awk-lösung:

    das stichwort für google lautet: "the csv problem" und vielleicht awk. leider find ich die seite gerade nicht mehr woher ich dann die funktionierende lösung hatte ..
    aber das hier sollte es irgendwie auch tun

    http://groups.google.com/group/comp....73d9e784c68dee

    moe
    AWK kennt keine Callbacks und die Regex Maschine hat die neuen
    Features nicht. Von daher kommst Du nur Umwege zum Ziel.
    Aber wenn es unbedingt AWK sein muß -- geht auch.
    Abriss, bzw. die Sprengung des World Trade Centers
    WDR Dokumentation
    Doku + DT Untertitel
    Weitere Infos - Terrorstorm

  9. #9
    Registrierter Benutzer Avatar von moedule
    Registriert seit
    04.10.2003
    Beiträge
    346
    nur aus gründen der vollständigkeit, ja ok es ist aufwendiger
    Code:
    #!/usr/bin/awk -f
    BEGIN { FS=SUBSEP; OFS="|" }
    
    {
      result = setcsv($0, ",")
      print
    
    }
    
    
    # setcsv(str, sep) - parse CSV (MS specification) input
    # str, the string to be parsed. (Most likely $0.)
    # sep, the separator between the values.
    #
    # After a call to setcsv the parsed fields are found in $1 to $NF.
    # setcsv returns 1 on sucess and 0 on failure.
    #
    # By Peter Strömberg aka PEZ.
    # Based on setcsv by Adrian Davis. Modified to handle a separator
    # of choice and embedded newlines. The basic approach is to take the
    # burden off of the regular expression matching by replacing ambigious
    # characters with characters unlikely to be found in the input. For
    # this the characters "\035".
    #
    # Note 1. Prior to calling setcsv you must set FS to a character which
    #         can never be found in the input. (Consider SUBSEP.)
    # Note 2. If setcsv can't find the closing double quote for the string
    #         in str it will consume the next line of input by calling
    #         getline and call itself until it finds the closing double
    #         qoute or no more input is available (considered a failiure).
    # Note 3. Only the "" representation of a literal quote is supported.
    # Note 4. setcsv will probably missbehave if sep used as a regular
    #         expression can match anything else than a call to index()
    #         would match.
    #
    function setcsv(str, sep, i) {
      gsub(/""/, "\035", str)
      gsub(sep, FS, str)
    
      while (match(str, /"[^"]*"/)) {
        middle = substr(str, RSTART+1, RLENGTH-2)
        gsub(FS, sep, middle)
        str = sprintf("%.*s%s%s", RSTART-1, str, middle,
          substr(str, RSTART+RLENGTH))
      }
    
      if (index(str, "\"")) {
        return ((getline) > 0) ? setcsv(str (RT != "" ? RT : RS) $0,
    sep) : !setcsv(str "\"", sep)
      } else {
        gsub(/\035/, "\"", str)
        $0 = str
    
        for (i = 1; i <= NF; i++)
          if (match($i, /^"+$/))
            $i = substr($i, 2)
    
        $1 = $1 ""
        return 1
      }
    
    }

  10. #10
    Registrierter Benutzer Avatar von Romanday
    Registriert seit
    03.02.2004
    Beiträge
    829
    Zitat Zitat von moedule
    nur aus gründen der vollständigkeit
    Mit Perl ist es noch einfacher.
    PHP-Code:
    sub g{$g=$_[0];$g=~tr/,//d;return $g;}$g=~ s/\"([^\"]+)\"/g($1)/eg; 
    Abriss, bzw. die Sprengung des World Trade Centers
    WDR Dokumentation
    Doku + DT Untertitel
    Weitere Infos - Terrorstorm

Lesezeichen

Berechtigungen

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