PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : awk suchen und ersetzen



Zambo
02-06-2005, 18:10
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

RapidMax
02-06-2005, 23:37
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

Hans-Georg Normann
03-06-2005, 00:19
VAR=${VARIABLE}
So kannte ich das noch garnicht. Ich hätte ein Script myawk.awk angelegt.
// { 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

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:
[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
awk '{ $3 = VAR; print }' FS=';' OFS=';' "VAR=${LOGNAME}" myFile.txterhalte ich genau das gleiche Ergebnis. Ich muss glaube ich doch noch mal RTFM machen :confused: Dann tröste ich mich wenigstens damit, das es einem Newbie zeigt, wie flexibel das Teil doch ist.

Hans

Zambo
06-06-2005, 12:25
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? :confused:

Gruss

Hans-Georg Normann
06-06-2005, 21:27
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.


#Statt
awk -f myawk.awk myFile.txt

#sollte dies auch gehen
MYFILE=./myFile.txt
awk -f myawk.awk $MYFILE


Hans

Jasper
07-06-2005, 00:54
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? :confused:


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

Zambo
07-06-2005, 13:23
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.

-Tobi-
07-07-2008, 14:36
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? :confused:

jan61
07-07-2008, 20:17
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

-Tobi-
08-07-2008, 09:58
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