PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : sed s/ mit zwei Variablen und internem count



skrolle
11-05-2010, 08:11
Hallo zusammen,

ich hätte da mal ne Frage.

Kann man mit dem Befehl sed zwei Sonderzeichen mit Zahlen ersetzen und eine davon hochzählen lassen?
Hintergrund:
Ich habe eine Basisdatei mit Sonderzeichen versehen, diese soll nun mehrmals aktualisiert werden, wobei das Zeichen ~ die Dateianzahl ist und das ZEichen § für jede einzelne Datei von 1 bis 10.000.000 hochgezählt werden soll.

folgendes habe ich in einer Datei stehen

<bla>~TD§</bla>
<bla>~TD§</bla>
<bla>~TD§</bla>
<bla>~TD§</bla>
...

rauskommen soll nun für die erste Datei

<bla>1TD1</bla>
<bla>1TD2</bla>
<bla>1TD3</bla>
<bla>1TD4</bla>
...
für die zweite Datei
<bla>2TD1</bla>
<bla>2TD2</bla>
<bla>2TD3</bla>
<bla>2TD4</bla>
...

Die ~ alleine zu ersetzen habe ich schon.
sed "s/~/$((zaehler))/" $testdatenverz/kleine_Datei.xml > $verbeitungsver/$stringname;

Nun will ich jedoch auch noch das Sonderzeichen $ ersetzen... aber wie?
Allein das hochzählen in dem Befehl sed klappt ja schon nciht, wie soll ich dann beide Ersetzungen in einem BEfehl vornehmen?

Folgenden Code habe ich gebastelt: (nur mit dem §)

sed "s/§/$((zaehler + 1))/" $testdatenverz/kleine_Datei.xml > $verbeitungsver/$stringname;

leider klappt das nicht so ganz, da der zaehler nicht automatisch hochzählt.

sed "s/§/$(($((zaehler + 1))))/" $testdatenverz/kleine_Datei.xml > $verbeitungsver/$stringname;
hat leider auch keine Veränderung gebracht.

Muss man hier ggf. mit awk zusammenarbeiten?

Vorab vielen Dank für Eure Hilfe.

Viele Grüße

skrolle

John W
11-05-2010, 13:10
Das sollte reichen:

FILE=testdatei

COUNT=1
for LINE in $(grep -n '~' "$FILE" | awk -F ':' '{print $1}')
do
sed -r $LINE's/~/'$COUNT'/' -i "$FILE"
COUNT=$(($COUNT+1))
doneEs werden nur Zeilen geändert, die durch grep gefunden werden (Zeilennummer wird als Referenz an sed gegeben), und da auch nur das erste Auftreten dieser Zeichenfolge.

skrolle
11-05-2010, 14:06
Hallo,

interessant...
Vielen Dank für die Hilfe!

Wie sieht da die Verarbeitungsgeschwindigkeit aus? Die Dateien haben teilweise mehr als 500.000.000 Zeilen.
Gibt es ggf eine schnellere Lösung?

Danke und Gruß

skrolle

msi
12-05-2010, 00:27
ziemlich inperformant ist die bash lösung von oben,
kannst zB mit perl sehr elegant lösen und performanter lösen




perl -i -pe 'BEGIN { $c=1 } s/~/$c/;s/§/$./; eof and close ARGV and $c++' datei1 datei2 datei3


oder wenn nicht die zeilennummer sondern pro § gezählt werden soll:



perl -i -pe 'BEGIN { $c=1 } s/~/$c/; s/§/++$z/eg; eof and close ARGV and $c++ and $z=0' datei1 datei2 datei3

skrolle
12-05-2010, 06:23
Hallo

ok..Perl..

ich denke, dass ich mit dem aufruf perl... aus einem bash-Programm das Perlskript laufen lassen kann.

Kann ich denn dem Skript auch Variabeln übergeben?

perl -i -pe 'BEGIN { $c=1 } s/~/$c/; s/§/++$z/eg; eof and close ARGV and $c++ and $z=0' datei1 datei2 datei3

@c$
$c bestimme ich schon vorher in einer Schleife. Diese Variable heißt bei mir $zaehler.

@datei1 datei2 datei3...
Wieviele Dateien bei mir generiert werden müssen kann ich nicht von Anfang an sagen, da über eine bestimmte Zeit Dateien generiert werden müssen.
Daher wird der Dateiname auch anhand einer laufenden Nummer bestimmt und in der Variabeln $verbeitungsver/$stringname übergeben

Kann man das Perl-Skript so oder ähnlich abändern?

perl -i -pe 'BEGIN { $c=$zaehler } s/~/$c/; s/§/++$z/eg; eof and close ARGV and $z=0' $verbeitungsver/$stringname

oder direkt

perl -i -pe 'BEGIN s/~/$zaehler/; s/§/++$z/eg; eof and close ARGV and $z=0' $verbeitungsver/$stringname

Beide Varianten habe ich versucht, leider sagt er mir "perl: command not found"

Ich frage jetzt erstmal Tante googel wie ich Perl aus bash heraus aufrufen kann...

Danke und Gruß

skrolle

msi
12-05-2010, 12:05
perl musst du wohl erstmal noch installieren,
ansonsten knanst du natürlich alles damit machen.
wenn du variablen von der bash reinhaben willst, musst
du halt schauen dass sie nicht in einem ' gequoteten string
stehen sondern zB in einem " gequoteten..

skrolle
12-05-2010, 12:55
Hallo,

ja, hatte ich auch schnell festgestellt, perl war nicht installiert.

Habe nun folgendes Eingefügt:

perl -i -pe 's/~/'$zaehler'/; s/@/++$z/eg; eof and close ARGV and $z=0' $verbeitungsver/$stringname;

Damit klappts nun.
Es wird nur für jede einzelne Datei eine Sicherung *.bak angelegt. Mal sehen wie ich das noch unterbinden kann.

Vielen Dank und Gruß

skrolle