# [sed + gawk] Strings zwischen Dateien verschieben



## mueslirocker (19. Dezember 2005)

Hallo!

Ich habe folgendes Problem:
Ich habe zwei Textdateien, in denen ich einige Strings ändern möchte.

Und zwar beinhalten beide Dateien (mehr als einmal) den String, beschrieben durch den regulären Ausdruck:
[A-Z]+[ ][0-9a-f]+

Ich möchte nun folgendes tun:
Ich suche in Datei B solche Strings.
Habe ich einen gefunden, so suche ich einen solchen String in Datei A, dessen ersten Teil dem gefundenen in Datei B entspricht.
Habe ich einen gefunden, möchte ich den zweiten Teil von Datei A nach Datei bei kopieren.

Beispiel:


```
Datei A:
ABC 0000
DEF 7777
XYZ 5555

Datei B:
ABC 1111
DEF 2222
GHI 3333
```

Als Ergebnis möchte ich Datei B verändert haben:


```
Datei A: unverändert

Datei B:
ABC 0000
DEF 7777
GHI 3333
```

Ich bin mir relativ sicher, dass das Problem mit sed und gawk gelöst werden kann.. nur leider hatte ich mit den schönen Tools noch nicht viel zu tun und kenn mich entsprechend wenig aus.

So, nun meine Ansätze:
gawk '/([A-Z]+)[ ]([0-9a-f]+)/ {print $2;}' dateiA.txt
liefert mir die Hex-Zahlen.. allerdings von allen gefundenen Strings.

Mit 
sed 's/\([A-Z]+\)[ ]\([0-9a-f]+\)//' dateiB.txt
wollte ich die Strings erstmal einfach nur löschen.
Allerdings werden sie nur ausgegeben.. und zwar alle Zeilen der Datei.

Ihr seht, dass ich schon recht früh stecken bleibe..
Wenn ich die beiden Zeilen richtig formulieren könnte, würde ich als nächstes gawk in sed einbauen müssen, richtig?
Ist es korrekt, dass \3 den String in der dritten runden Klammer des Ausdrucks wiedergibt?
Ich müsste entsprechend bei der Ersetzung von sed den ersten Teil \1 übernehmen, das Freizeichen von Hand einbauen und statt dem zweiten Teil den Rückgabewert von gawk benutzen ($2 oder?), wobei ich bei gawk nicht [A-Z]+ sondern \1 angeben muss.
Ist das korrekt?

Kann mir jemand bei der Syntax helfen?

/edit
Habe vergessen zu erwähnen, dass sonstige Zeichen/Zeilen/... in Datei B erhalten bleiben sollen. Hoffe, das macht sed schon automatisch.
Aber falls nicht - wie kann ich das gewährleisten?


----------



## RedWing (19. Dezember 2005)

> Ist es korrekt, dass \3 den String in der dritten runden Klammer des Ausdrucks wiedergibt?
> Ich müsste entsprechend bei der Ersetzung von sed den ersten Teil \1 übernehmen, das Freizeichen von Hand einbauen und statt dem zweiten Teil den Rückgabewert von gawk benutzen



Soweit passt des ganz gut.


> ($2 oder?)


$2 ist das 2te Feldelement was awk beim parsen des Textes übergeben wird.
Der "Rückgabewert" von awk ist das was du mittels der awk print Funktion
auf stdout ausdruckst...


> , wobei ich bei gawk nicht [A-Z]+ sondern \1 angeben muss.


Du kannst im awk nicht auf einen Ausdruck aus dem sed referenzieren, ich denke 
das sollte so nicht funktionieren...

Also ich hätte da zwei varianten anzubieten.
Einmal mit Shellvariablen:


```
#! /bin/bash
SEARCH="DEF"
WORD=`grep $SEARCH' [0-9a-f]\+' fileA | awk -F ' ' '{print $1}'`
NUMBER=`grep $SEARCH' [0-9a-f]\+' fileA | awk -F ' ' '{print $2}'`
cat fileB | sed 's/\('$WORD'\) [1-9a-f]\+/\1 '$NUMBER'/' > fileB
```

und einmal auch ohne. Muesstest dann halt entsprechend 
Kommandosubstitution im sed durchführen...

Gruß

RedWing


----------

