PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : sed: alles ersetzen bis auf...



tempestas
12-10-2010, 14:39
Hallo,

so schwierig kann es nicht sein, aber irgendwie finde ich die Lösung nicht.
Ich möchte in vielen .eps Dateien den font name "Helvetica" durch "Arial" ersetzen und zwar in allen Zeilen bis auf 4.
Diese 4 Zeilen können an unterschiedlichen Stellen in den Dateien stehen, haben aber eine Gemeinsamkeit: die letzte der 4 Zeilen beginnt mit einer bestimmten Zeichenkette.

Bis hierhin bin ich gekommen:



for j in *.eps;
do
mv $j $j.old
sed -e 's/Helvetica/Arial/g' -e 's/CMR10/Arial/g' -e 's/CMMI10/Arial/g' $j.old > $j
cat $j | grep "^[(\242) s]" -A 4 | sed 's/Arial/CMR10/g' $j
rm -f $j.old
epstopdf $j
done


Meine Problemzeile ist diese hier:

cat $j | grep "^[(\242) s]" -A 4 | sed 's/Arial/CMR10/g' $j

Wie bekomme ich diese wieder an die Stelle in der neuen Datei, wo ich sie hergeholt hab? Oder denke ich zu kompliziert? Ich hab in der Dokumentation von sed leider keine Möglichkeit gefunden, wie bei grep zu sagen, dass man mehrere Zeilen vor einer bestimmten Zeile addressiert.

Vielen Dank im Voraus für wertvolle Tipps!

tempestas

John W
12-10-2010, 17:35
sed '4!s#Helvetica#Arial#g' -i dateiEDIT: Blödsinn, nicht richtig gelesen...

Hier das ist das, was du suchst:

sed '/^stop/!s#Helvetica#Arial#g' -i dateistop ist dabei die Zeichnekette, die nicht am Anfang stehen darf - due kannst einen kompletten RegEx aufbauen, der als Ausschlusskriterium gelten soll (ohne ! wird es zur notwendigen Bedingung).

tempestas
12-10-2010, 17:57
Hier das ist das, was du suchst:

sed '/^stop/!s#Helvetica#Arial#g' -i dateistop ist dabei die Zeichnekette, die nicht am Anfang stehen darf - due kannst einen kompletten RegEx aufbauen, der als Ausschlusskriterium gelten soll (ohne ! wird es zur notwendigen Bedingung).

Vielen Dank für die schnelle Antwort! Allerdings habe ich eine dumme :o Rückfrage.

Wenn ich Deinen Codeschnipsel richtig verstehe, dann sagt er: ersetze in jeder Zeile AUßER in der, die mit "stop" beginnt (oder wahlweise mit meiner Zeichenkette "(\242) s") das "Helvetica" durch "Arial", richtig?
Aber dann hab ich immer noch das Problem, dass ich ja auch in den 4 Zeilen, die vor dem "stop" bzw. meiner Zeichenkette kommen, das "Helvetica" nicht ersetzen will. Und da diese 4 Zeilen eben mit derselben Zeichenkette starten wie alle anderen Zeilen, kann ich ja diese nicht als RegEx formulieren.

Und eine noch dümmere :o Frage: warum schreibst Du "#" statt "/"? Gehört das zum Befehl? :o :o :o

Vielen Dank!

tempestas

John W
12-10-2010, 18:20
Heute bin ich nicht ganz auf der Höhe...

Bereiche kann man so addressieren: zeile,zeile (z.B. 1,4d um die ersten 4 Zeilen zu löschen).
grep kann auch nur die Zeilen ausgeben, dann könnte man den Zeilenbereich damit ausdrücken:


line="$(grep '^[(\242) s]' -nh datei | awk -F ':' '{print $1 ; exit(0); }')"
sed $((line-3)),$line'!s#Helvetica#Arial#g' datei

Das nimmt lässt jetzt die Zeile mit dem Treffer und die drei Zeilen davor, wie sie sind und ersetzt den Rest - ich hoff mal, ich hab das jetzt so richtig verstanden.

PS: Ich schreib # statt / weil ich es besser lesen kann - sed ist das egal, solange das Zeichen nach s auch am Ende und als Trenner zwischen Suchmuster und Ersetzungsmuster steht (auf die Spitze getrieben könnte man auch Leerzeichen nehmen: "sed 's a b g'").

tempestas
12-10-2010, 21:41
Hm, das klappt nicht richtig :-(

Ich hab es angepasst (und hoffentlich keinen Fehler dabei gemacht?)


for j in *.eps;
do
mv $j $j.old
sed 's/Helvetica/Arial/g' $j.old > $j
rm -f $j.old
mv $j $j.old
line="$(grep '^[(\242) s]' -nh $j.old | awk -F ':' '{print $1 ; exit(0); }')"
sed -e $((line-3)),$line'!s/CMMI10/Arial/g' -e $((line-3)),$line'!s/CMR10/Arial/g' $j.old > $j
rm -f $j.old
epstopdf $j
done


So sahen die betreffenden Zeilen aus:


%%IncludeResource: font CMR10
/CMR10 /ISOLatin1Encoding 216 FMSR

669 3159 mt -90 rotate
(\242) s

Und das ist das Ergebnis:


%%IncludeResource: font Arial
/Arial /ISOLatin1Encoding 216 FMSR

669 3159 mt -90 rotate
(\242) s

d.h. die Zeilen, in denen das "CMR10" eigentlich nicht ersetzt werden sollte, wurde es ersetzt.

Was hab ich falsch gemacht?


Schönen Abend,
tempestas

John W
12-10-2010, 21:47
for j in *.eps;
do
mv $j $j.old
sed 's/Helvetica/Arial/g' $j.old > $j
rm -f $j.old
mv $j $j.old
line="$(grep '^[(\242) s]' -nh $j.old | awk -F ':' '{print $1 ; exit(0); }')"
sed $((line-3)),$line's/CM(MI|R)10/Arial/g' $j.old > $j
rm -f $j.old
epstopdf $j
done

So vielleicht? Gib am besten auch ein Beispiel, WIE das denn richtig aussieht!