Sed od. Awk - Ersetzen unbekannter parameter

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von JulianB, 24.09.2008.

  1. #1 JulianB, 24.09.2008
    JulianB

    JulianB Grünschnabel

    Dabei seit:
    24.09.2008
    Beiträge:
    6
    Zustimmungen:
    0
    Hallo liebes Forum,

    tja mein erster Post gleich ne Frage. Sorry.

    Ich habe ein Textfile indem sich verschiedene Strings befinden. Diese String muss ich nach einem bestimmten Suchparameter durchforsten, Wenn ich diesen Parameter gefunden habe muss ich in dem gleichen Satz die 3, hinter dem Parameter stehenden, Wörter durch einen Platzhalter ersetzen.

    Z.B.

    Text text SFTP_CP_NU Wort1 Wort2 Wort3 Pfad Pfad Dateiname.dat

    So ich weiß das sich in dem Satz SFTP_CP_NU befindet, d.h. ich muss danach suchen. Ersetzen will ich aber Wort1-3, diese sind durch leerzeichen getrennt.

    Ich weiß nur, diese drei zu ersetzenden Wörter stehen hinter SFTP_CP_NU, es sind immer 3, sie sind durch blanks getrennt und hinter dem dritten folgen weitere Angaben.

    Jetzt der größte Punkt warum ich nach Hilfe schreie: Ich habe weder von Sed noch von Awk Ahnung ^^. War immer mit Perl zufrieden, aber das kann ich jetzt nicht nutzen.

    Kann mir jemand helfen???

    Liebe Grüße,
    Julian
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. rikola

    rikola Foren Gott

    Dabei seit:
    23.08.2005
    Beiträge:
    2.133
    Zustimmungen:
    0
    Wenn Du es mit perl nicht machen kannst, klingt das sehr nach Hausaufgabe. Daher nur ein paar hinweisende Fragen
    - wie wuerdest Du es denn mit Perl machen?
    - wieviel weisst Du ueber regulaere Ausdruecken?
    - Wenn man in sed einen regulaeren Ausdruck mit \(...\) umschliesst, kann man ihn mit \# referenzieren, wobei '#' die Anzahl der \(..\) Ausdruecke zaehlt.
     
  4. #3 JulianB, 24.09.2008
    Zuletzt bearbeitet: 24.09.2008
    JulianB

    JulianB Grünschnabel

    Dabei seit:
    24.09.2008
    Beiträge:
    6
    Zustimmungen:
    0
    Nein mit Hausaufgabe hat das rein garnichts zu tun. Ich brauche das Script für die bearbeitung von Logs auf Solarismaschinen. In Perl würde ich das ganze so lösen:

    Code:
    use strict;
    use warnings;
    
    my $buffer = '';
    my $filename = $ARGV[0];
    my $replace = '';
    my $SUP = 'Platzhalter';
    my $change = '';
    my $new = '';
    my @data;
    
        foreach $replace(@data)
        {
           if(index($replace,"SFTP_CP_NU") != -1)
           {
            $replace =~ m/^(.*)("SFTP_CP_NU" {1})([A-Za-z0-9_\.\,\+\*-]*)( {1}[A-Za-z0-9_\.\,\+\*-]*)( {1}[A-Za-z0-9_\.\,\+\*-]*)( {1}.*)$/;
            local $FIRST=$1;
            local $FTP=$2;
            local $LAST=$6;
            $buffer=$FIRST;
            $buffer.=$FTP;
            $buffer.=$SUP;
            $buffer.=$LAST;
            $buffer.="\n";
            $replace = $buffer;
           }
        }
    

    So in etwa jedenfalls, den gesamten Code kann ich leider nicht posten. Nur jetzt mit SED und AWK habe ich keine ahnung....

    Aber nochmal, keine Hausaufgaben, aber Perl ist trotzdem nicht möglich.

    Liebe Grüße,

    Julian

    PS: Das was du in meinem Perl Beispiel siehst ist alles was ich von RegEx weiß, sprich nicht viel, aber ich glaube einigermaßen genug.

    ___________________________________

    Ergänzung:

    Mit Awk bin ich jetzt so weit, das ich den gewünschten Parameter finde:

    Code:
    cat test |awk '
    {n=split($0,Array," ")
    for(i=1; i<NF; i++)
    {
    if(Array[i] == "SFTP_CP_NU")
    {
    print $i
    }
    }
    }'
    
    Jetzt muss ich nur die darauf folgenden 3 Felder bearbeiten, sprich deren Inhalt durch einen anderen Inhalt ersetzen. Geht das mit Awk??? (Solaris, ksh)
     
  5. #4 Wolfgang, 24.09.2008
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo
    Das geht wunderbar mit sed:
    Code:
    $ cat file
    text Suchtext Wort1 Wort2 Wort3 foo bar foobar
    text text Wort1 Wort2 Wort3 foo bar foobar
    sed -e '/Suchtext/s/\(.* Suchtex[[:space:]]\+\)\([^[:space:]]*[[:space:]]\{1\}\)\{3\}\(.*\)$/\1Rep1 Rep2 Rep3 \3/'
    text Suchtext Rep1 Rep2 Rep3 foo bar foobar
    text text Wort1 Wort2 Wort3 foo bar foobar
    
    POSIX:
    Code:
    [[:space:]]
    statt Leerzeichen, sollte also auch auf Solaris laufen.

    Merke: Negationen erleichtern bei RegExp oft das Leben. ;)
    Hier nicht Leerzeichen
    Code:
    [^[:space:]]
    Gruß Wolfgang
     
  6. rikola

    rikola Foren Gott

    Dabei seit:
    23.08.2005
    Beiträge:
    2.133
    Zustimmungen:
    0
    Der Perl code ist ja auch schon recht nahe an einer Loesung. Ein wichtiger Unterschied ist, dass man Bloecke an regulaeren Ausdruecken mit \(...\) referenzieren kann, waehrend es in Perl mit einfachen Klammen zu gehen scheint.
     
  7. #6 JulianB, 25.09.2008
    Zuletzt bearbeitet: 25.09.2008
    JulianB

    JulianB Grünschnabel

    Dabei seit:
    24.09.2008
    Beiträge:
    6
    Zustimmungen:
    0
    Korrekt in Perl werden die RE's in einfache "()" gesetzt, ein Grund mehr warum ich mit SED wohl nie ganz klar gekommen wäre.

    Bin ja letzendlich auch auf Awk gekommen, ich bin nunmal leider mehr für eine C/C++ Schreibweise geboren als für ewig lange RE's ^^. Aber ich will trotz alledem es mit SED versuchen.

    Also Wolfgang:

    Erstmal vielen vielen Dank für die sehr schnelle Antwort, ich werde es sofort austesten und mich dann melden.
    PS: Negation in RE's kenne ich ^^.

    Liebe Grüße,

    Julian
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    Hallo Wolfgang,

    ich habe dein Code eben getestet, nur irgendwie tut sich garnichts. Ich habe ihn angepasst (also nur Suchtext durch SFTP_CP_NU ersetzt). Doch ich bekomme weder Fehlermeldungen noch bekomme ich ein Ergebnis.

    Die Datei wird ausgegeben, geändert hat sich nichts.

    Zu deinen RegEx habe ich allerdings eine Frage, irgendwas will da nicht in meinen Kopf.

    Wenn ich das richtig verstehe suchst du mit SED nach dem Wort "Suchtext" Zeile f. Zeile, wenn "Suchtext" in Zeile vorkommt, rufst du deine Regex auf, diese findet "Suchtext"+Blank und danach beliebig viele Nichtblanks bis wieder ein Blank auftaucht
    Code:
     \([^[:space:]]*[[:space:]]\ 
    das ganze 3 mal {3} bis zum Zeilenende $/.

    Okidoki, nur wie funktioniert der letzte Teil deiner Regex??? Ersetzt du den geklammerten Ausdruck vor Klammer 3 durch Rep1 -3?? Magst du mir den Teil vll einmal erklären???

    Danke.
     
  8. #7 Wolfgang, 25.09.2008
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo

    \1 ist der Inhalt von der ersten Klammer, also der Text vor Suchtext + der Suchtext selbst + ein Space.
    Dann füge ich drei Worte ein REP(LACE) 1 bis 3
    Dann häng ich den Text nach \2 Klammerpaar 2 ein.

    Die Backreferenzen funktionieren bei sed genau wie bei Perl $1 bei perl entspricht hier \1

    Wolfgang
     
  9. #8 JulianB, 25.09.2008
    JulianB

    JulianB Grünschnabel

    Dabei seit:
    24.09.2008
    Beiträge:
    6
    Zustimmungen:
    0
    Hallo Wolfgang,

    okay, aber warum klappt das einfach nicht. Ich habe auf meiner Solarismaschine sogar deinen Probetext benutzt. Aber mit deinen RegEx bekomme ich zwar keine Fehlermeldung aber wenn ich den durch SED geänderten Inhalt in eine zweite Datei schreibe test1>test2 dann steht in test2 genau dasselbe wie in test1, sprich es hat sich nichts geändert...ich verstehe das nicht. Ich habe schon an deinem Befhel alle [[:space:]] durch normale Blanks ersetzt, daran lag es nicht. Ich habe auch den Befehl /g gesetzt. Auch das wars nicht. Irgendwie findet er die Zeile nicht, bzw. sucht das falsche.

    Code:
    e '/Suchtext/s/\(.*
    Kann man hier nicht eigentlich das /Suchtext/ einfach weglassen???

    LG
     
  10. #9 Wolfgang, 25.09.2008
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo
    Ja, das kannst du auch weglassen.
    Ist nur für Performance relevant, da im Falle des Nichtvorkommens garnicht erst die RegExp-Engine angeworfen wird.

    Aber dann teste doch erstmal, ob dein SUCHTEXT überhaupt gefunden wird?

    Code:
    sed -ne '/SUCHTEXT/p' input
    
    Hier wird die Zeile nur ausgegeben, wenn SUCHTEXT gefunden wird.

    Wolfgang
     
  11. #10 JulianB, 25.09.2008
    Zuletzt bearbeitet: 25.09.2008
    JulianB

    JulianB Grünschnabel

    Dabei seit:
    24.09.2008
    Beiträge:
    6
    Zustimmungen:
    0
    Hey Wolfgang,

    erstmal vielen vielen Dank für die Superhilfe die ich hier bekomme. Das erlebe ich sehr sehr selten wenn ich eine Frage in einem Forum stelle. Wirklich Top.

    Back to Topic:

    Wenn ich nur nach dem Suchbegriff parse bekomme ich genau die richtige Zeile ausgegeben, daran kann es schonmal nicht liegen....

    Wie jetzt weiter? Ich grübel mir gerade die Birne heiß :think:

    Liebe Grüße aus dem hohen Norden,

    Julian

    .
    .
    .
    EDIT :
    .

    Mir sind gerade ein paar Sache aufgefallen:

    Wenn ich vor dem Suchwort in der Klammer od. in einer anderen Klammer .* stehen habe, dann findet er in der gesamten Zeile nichts.

    Sprich bei:
    Code:
    \(.* SFTP_CP_NU\)
    wird nichts angezeigt im Gegensatz zu:

    Code:
    \(SFTP_CP_NU\)
    Jetzt habe ich auch noch das Problem wenn ich hinter einen geklammerten Ausdruck wie Wolfgang gesagt hat {3} setze, scheint diese garnicht wiederholt zu werden...kann man geklammerte Ausdrücke überhaupt wiederholen, oder gilt das {n} nur für Zeichen?

    LG Julian
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    Na Wolfgang, spaß vergangen??? Nein, war nur ein Scherz ;)

    So was habe ich rausbekommen:

    Solaris scheint die eckigen Klammern [] nicht zu mögen.

    Die RegEx scheint von hinten (rechts) abgelaufen zu werden, sprich:

    Code:
    cat file
    
    Txt1 txt2 Suchwort txt3 txt4 txt5 txt6 txt7 txt8 txt9
    
    \(Suchwort\)   \{1\}\(.*\)    \{1\}\(.*\)    \{1\}\(.*\)
    
    /1 enthält nun das Suchwort
    /2 enthält txt3
    /3 enthält txt4-8
    /4 enthält txt9

    Wieso das???? Ich verstehe das nicht, bei Perl wäre jetzt in /1 das Suchwort in /2 wäre txt3 in /3 wäre txt4 in /4 wäre txt5 usw...

    Naja ich prussel hier noch weiter...

    LG
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    So meine Lieben, insbesondere Wolfgang,

    Ich habe es tatsächlich gelöst bekommen, ohne Eure Hilfe aber sicher nicht!!!

    Code:
    s/\.*\( \{1\}SFTP_CP_NU\) \{1\}\([A-Za-z0-9_\.\,\+\*-]* \{1\}[A-Za-z0-9_\.\,\+\*-]* \{1\}[A-Za-z0-9_\.\,\+\*-]*\) \{1\}\(.*\)$/\1 XXX XXX XXX \3/
    
    Nicht unbedingt die schönste Variante, wie ich mir denke. Aber sie funktioniert UND sie ist absolut Solariskompatibel ^^.

    Vielen Dank nochmal,

    Julian.

    ...ACHJA:

    Gibt es soetwas wie -i auch auf Solaris????

    Cya
     
  12. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  13. #11 Wolfgang, 25.09.2008
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    So, nun meine Antwort.
    Die Lust ist mir nicht vergangen, war schlicht und ergreifend Unterwegs.

    Zum Thema:
    Habe hier kein Solaris zur Verfügung, deshalb kenne ich die von dir verwendete sed.Version auch nicht.
    Möglicherweise unterstützt ja das sed bei Solaris nicht die erweiterten RE-Funktionen.
    Mein Vorschlag ist insofern nur als Denkanstoß zu nehmen, was du ja nun auch gemacht hast.
    Mich würde schonmal interessieren, wie negierte Zeichenklassen bei deinem sed verwendet werden.
    Laut Manpage im Netz:
    müsstest du also das Leerzeichen mit [^ ] darstellen können.


    Aber eventuell kannst du ja mal schauen, ob GNU sed unter deinem Solaris installiert ist.
    Müsstest du dann mit vollem Pfad aufrufen.

    Gruß Wolfgang
     
  14. #12 JulianB, 26.09.2008
    JulianB

    JulianB Grünschnabel

    Dabei seit:
    24.09.2008
    Beiträge:
    6
    Zustimmungen:
    0
    Jop stimmt, habs nochmal getestet die Negation von Blanks [^ ] funktioniert sehr gut.

    Danke an euch alle und :CLOSED: ;)
     
Thema:

Sed od. Awk - Ersetzen unbekannter parameter

Die Seite wird geladen...

Sed od. Awk - Ersetzen unbekannter parameter - Ähnliche Themen

  1. [Gelöst] Suchen und ersetzen mit Hilfe mehrerer Parameter

    [Gelöst] Suchen und ersetzen mit Hilfe mehrerer Parameter: Hallo zusammen, ich bin an einem Punkt angekommen, wo ich nicht mehr weiter komme und hoffe ihr könnt mir weiter helfen. Anbei ein Ausschnitt aus...
  2. Snappy Personal soll bei Ubuntu langfristig Debians Paketformat ersetzen

    Snappy Personal soll bei Ubuntu langfristig Debians Paketformat ersetzen: Bereits vor mehreren Wochen gab Will Cooke von Canonical bekannt, für Ubuntu 15.10 werde ein Image, basierend auf der Snappy-Core-Technologie,...
  3. Wertebereich ersetzen mit sed

    Wertebereich ersetzen mit sed: Hallo Forenmitglieder, ich habe ein kleines Problem mit sed und zwar möchte ich in einer Datei mit mehren Spalten und Zeilen das Vorkommen eines...
  4. sed suchen und ersetzen mit Variable übergeben?

    sed suchen und ersetzen mit Variable übergeben?: hallo, ich habe folgenden sed-Befehl, der schon super ist und auch alles tut, was er tun soll, nur eben natürlich das $i einfach hinschreibt...
  5. Unterschiedlichen Text in mehrere Dateien finden und löschen / ersetzen

    Unterschiedlichen Text in mehrere Dateien finden und löschen / ersetzen: Moin erstmal, ich suche nach einer Möglichkeit, in mehreren unterschiedlichen Dateien Text mit folgendem Muster zu suchen und zu löschen oder...