Ergebnis 1 bis 10 von 10

Thema: awk suchen und ersetzen

  1. #1
    Zambo
    Gast

    awk suchen und ersetzen

    Hallo,

    irgendwie bin ich zu blöd als awk-Newbie folgendes zu realisieren:

    In einem Shellscript soll ein awk-Aufruf in einer Datei das 3. Feld (Trennzeichen ";") durch eine Shellscriptvariable ersetzen.


    Kann mir jemand helfen?


    Gruss

  2. #2
    Registrierter Benutzer
    Registriert seit
    05.09.2002
    Ort
    Neuhausen
    Beiträge
    320
    Code:
    awk '{ $3 = VAR; print }' FS=';' OFS=';' "VAR=${VARIABLE}" file.csv
    Beschreibung: FS=';' setzt den Eingabefeldtrenner auf das Semikolon und OFS=';' den Ausgabefeldseparator ebenfalls auf das Semikolon, da sonst stattdessen Leerzeichen ausgegeben werden.
    $3 = VAR weist den Wert der (awk) Variablen VAR dem dritten Feld zu und print schliesslich sorgt dafür das die Zeile auch ausgegeben wird (wie das explizite print $0).
    Zum Schluss noch zum Weg der Shellvariablen in awk: Das Argument VAR=${VARIABLE} weist der (awk) Variablen VAR den Wert der (shell) Variablen $VARIABLE zu.

    Gruss, Andy

  3. #3
    Registrierter Benutzer Avatar von Hans-Georg Normann
    Registriert seit
    04.03.2000
    Ort
    Uetersen
    Beiträge
    571
    Zitat Zitat von RapidMax
    VAR=${VARIABLE}
    So kannte ich das noch garnicht. Ich hätte ein Script myawk.awk angelegt.
    Code:
    // { substitute_field(3) }
    
    
    BEGIN {
      #Zugriff auf $LOGNAME
      myLogin=ENVIRON["LOGNAME"]
      printf("\n")
    }
    
    END { }
    
    function substitute_field(feldNr) {
       # n = Anzahl der  gebideten Element im Array
       n = split($0, aFeld, ";")
    
       for(i=1; i<=n; ++i) {
         if(i == n) {
           trennzeichen = "\n"
         } else {
           trennzeichen = ";"
         }
    
         if(i==feldNr) 
           printf("%s%s", myLogin, trennzeichen)
         else
           printf("%s%s", aFeld[i], trennzeichen)
         
       }
    }
    Damit wir noch was zum spilen haben, hier die Textdatei myFile.txt
    Code:
    Feld1_1;Feld2_1;Feld3_1;Feld4_1
    Feld1_2;Feld2_2;Feld3_2;Feld4_2;Feld5_2
    Feld1_3;Feld2_3;Feld3_3;Feld4_3
    Feld1_4;Feld2_4;Feld3_4;Feld4_4;Feld5_4;Feld6_4
    Feld1_5;Feld2_5;Feld3_5;Feld4_5
    Feld1_6;Feld2_6;Feld3_6
    das ganze ergibt bei Ausführung:
    Code:
    [hans@rosi awk]$ awk -f myawk.awk myFile.txt
    
    Feld1_1;Feld2_1;hans;Feld4_1
    Feld1_2;Feld2_2;hans;Feld4_2;Feld5_2
    Feld1_3;Feld2_3;hans;Feld4_3
    Feld1_4;Feld2_4;hans;Feld4_4;Feld5_4;Feld6_4
    Feld1_5;Feld2_5;hans;Feld4_5
    Feld1_6;Feld2_6;hans
    [hans@rosi awk]$
    mit
    Code:
    awk '{ $3 = VAR; print }' FS=';' OFS=';' "VAR=${LOGNAME}" myFile.txt
    erhalte ich genau das gleiche Ergebnis. Ich muss glaube ich doch noch mal RTFM machen Dann tröste ich mich wenigstens damit, das es einem Newbie zeigt, wie flexibel das Teil doch ist.

    Hans
    333 Mhz, 466 MHz, neee, ich hab was neues zuhause.....

  4. #4
    Zambo
    Gast
    Erstmal vielen Dank an alle.

    Dieses hier:

    awk '{ $3 = VAR; print }' FS=';' OFS=';' "VAR=${VARIABLE}" file.csv

    funktioniert.

    Habe aber das Problem, das der Dateiname auch eine Variable ist und awk diese aber nicht annimmt.
    Also file.csv ist in meinem Fall ${ZEILE}.
    Ist es nicht möglich eine Variable als Dateinamen zu übergeben?

    Gruss

  5. #5
    Registrierter Benutzer Avatar von Hans-Georg Normann
    Registriert seit
    04.03.2000
    Ort
    Uetersen
    Beiträge
    571
    Hi Zambo

    warum machst du dir das Leben so schwer? Wenn du mit dem komplexen Einzeiler nicht klar kommst, warum nimmst du dann nicht einfach meine Variante mit dem externen Script? Das sollte überschaubarer sein, weil du ein Shellscript und ein awk Script hast.

    Code:
    #Statt 
    awk -f myawk.awk myFile.txt
    
    #sollte dies auch gehen
    MYFILE=./myFile.txt
    awk -f myawk.awk $MYFILE
    Hans
    333 Mhz, 466 MHz, neee, ich hab was neues zuhause.....

  6. #6
    Registrierter Benutzer
    Registriert seit
    26.12.2002
    Ort
    Matrix
    Beiträge
    194
    Zitat Zitat von Zambo
    Habe aber das Problem, das der Dateiname auch eine Variable ist und awk diese aber nicht annimmt.
    Also file.csv ist in meinem Fall ${ZEILE}.
    Ist es nicht möglich eine Variable als Dateinamen zu übergeben?
    das hat nichts mit awk zu tun. gehen tuts auf jeden fall.

    awk '{ $3 = VAR; print }' FS=';' OFS=';' "VAR=${VARIABLE}" "${ZEILE}"

    funktioniert nicht? wenn nicht, fehlermeldung mit skriptschnipsel bitte.


    -j

  7. #7
    Zambo
    Gast
    Habe jetzt die komplette Lösung mit awk:

    Um es nochmal zu erklären:

    In einer Datei ($DATEI) soll in jeder Zeile das dritte Feld durch eine stets fortlaufende Nummer ersetzt werden, also pro Zeile einen Zähler +1.
    Die Startposition der lfd. Nr. steht in einer Shellvariable ($LFDNR) drin.

    So sieht es aus und funktioniert:

    awk -F";" -v lfd=$LFDNR ' BEGIN { feld3=lfd++ } { $3= feld3++ ; for (lauf=1; lauf<NF; lauf++ ) { printf("%s;",$lauf) } printf("\n") } ' $DATEI>$DATEI_NEU


    Vielen Dank nochmal an alle.
    Geändert von Zambo (07-06-2005 um 12:26 Uhr)

  8. #8
    -Tobi-
    Gast

    ähnliches Problem

    Hi,

    ich bin ein absoluter Neuling beim awk.

    Ich habe eine Datei (test.xml) und will aus einer Zeile die die IP-Adresse enthält, die IP ändern und dann die komplette Datei mit der geänderten IP als text_2.xml abspeichern.

    angefangen habe ich mit

    less test.xml | awk /address/ > test_2.xml

    Allerdings liefert der awk mir dann logischer Weise folgende Zeile in der xml Datei:

    <network address="192.168.0.1" physical="bge0"/>

    Wie soll ich weitermachen?

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

    also erstmal wäre es gut, mit einem neuen Problem auch einen neuen Thread anzufangen.

    So ganz verstehe ich Deinen Ansatz noch nicht. Was soll denn beim awk rauskommen? Du führst doch überhaupt keine Aktion aus. Du filterst lediglich nach einer Zeile, die das Suchmuster "address" enthält. Und warum der less am Anfang? Übergib dem awk direkt den Dateinamen, ohne ihn vorher unnützerweise durch ein extra Kommando und eine Pipe zu jagen.

    Noch ne Frage: Wie sieht die Eingangsdatei aus? Ist die zu ändernde IP fest oder willst Du sie als Parameter übergeben oder willst Du beliebige IP-Adressen ändern?

    Wie Du weitermachen sollst? Stöber z. B. hier im Forum nach Beispielen, wie awk eingesetzt wird. Schau Dir Alternativen an (z. B. sed, der ist für solche Straight-Forward-Ersetzungen deutlich besser geeignet, auch dafür findest Du hier Beispiele in Hülle und Fülle), lies die Manual-Pages.

    Jan

  10. #10
    -Tobi-
    Gast
    Danke für den Tip mit sed und sorry wegen dem Thread

    Meine Lösung:

    sed 's/"192.168.0.1"/"$2"/g' /test.xml > tmp; mv tmp /test_2.xml

    ($2 wird als Parameter übergeben)

    gnz simpel, eigentlich xD

Lesezeichen

Berechtigungen

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