Sonie
Anmeldungsdatum: 1. Mai 2012
Beiträge: 133
Wohnort: Höchst im Odenwald
|
Ich möchte folgendes machen:
Bsp. Suchbegriff="zu suchen"
Ersatz="zu ersetzen"
sed -i /s/$Suchbegriff/$Ersatz/g Zieldatei da es so viele sind, wollte ich das extern einpflegen Script-File:
Datei_Name,SED_Anweisungen
Datei_name,SED-Anweisung
zu_bearbeitende_datei,s/$Suchbegriff/$Ersatz/g diese wird eingelesen und soll dann ausgeführt werden.
while read line; do
this=$(cut -d, -f2 <<< $line)
sed -i "$(this)" $(cut -d, f1 <<< $line)
done < $Script-File
ergibt dann als Ergebnis: sed -i "s/$Suchbegriff/$Ersatz/g" "zu_bearbeitende_datei"
soll aber geben:
sed -i "s/zu suchen/zu ersetzen/g" "zu_bearbeitende_datei"
wie bekomme ich die Variablen in den Variablen aufgelößt?
|
ChickenLipsRfun2eat
Anmeldungsdatum: 6. Dezember 2009
Beiträge: 12067
|
Hallo! Ob das mit dem Auflösen und übergeben der Variablen so funktioniert, weiß ich auch nicht. Falls die Variableninformation enthalten ist, könntest du sie mit $(echo $Suchbegriff) auflösen lassen. Meine eigentliche Frage dazu ist: Hast du immer den selben Suchbegriff und die selbe Ersetzung bei vielen Dateien? Da wäre vermutlich ein find /Pfad -type f -name "*.wannachange" -exec sed -i s/foo/bar/g einfacher.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Sonie schrieb: Ich möchte folgendes machen:
Bsp. Suchbegriff="zu suchen"
Ersatz="zu ersetzen"
sed -i s/$Suchbegriff/$Ersatz/g Zieldatei
...
Was hältst Du davon, sämtliche sed -Befehle in ein entsprechendes Skript auszulagern, und das dann an sed zu verfüttern ? Das Skript sed_test | #!/bin/sed -f
s/such/find/g
s/bier/wein/g
# usw. beliebige sed-Befehle
|
liefert: track@track:~$ cat sed_test.txt
versuch 1
probier 2
tu das nich 3
track@track:~$ sed -i -f sed_test sed_test.txt
track@track:~$ cat sed_test.txt
verfind 1
prowein 2
tu das nich 3
Normalerweise könnte man das Skript dank des Shebang auch direkt aufrufen, aber das klappt anscheinend mit der Option -i nicht. LG, track Edit: ... ah - man kann damit sogar eine nackte Änderungsliste verarbeiten, wenn man die fehlenden Befehle mit einem 2. sed in einer Process Substitution ergänzt ! Mit meiner Änderungsliste wird das: track@track:~$ cat sed_liste # Dies ist meine Liste:
find/such
wein/bier
tu/mach
track@track:~$ sed 's|^|s/|; s|$|/g|' sed_liste # ergänze die Befehle mit 2. sed:
s/find/such/g
s/wein/bier/g
s/tu/mach/g
track@track:~$ sed -f <( sed 's|^|s/|; s|$|/g|' sed_liste ) sed_test.txt # und verfüttere die Ausgabe an das 1. sed:
versuch 1
probier 2
mach das nich 3 geht also auch so !
|
Sonie
(Themenstarter)
Anmeldungsdatum: 1. Mai 2012
Beiträge: 133
Wohnort: Höchst im Odenwald
|
Ich habe hier diesen Beitrag gefunden, da wird diese Funktion mir der geschweiften Klammer dargestellt. | http://stackoverflow.com/questions/2634590/bash-script-variable-inside-variable
|
aber funktionieren tut es bei mir nicht... 😢 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | #/bin/bash
echo "Test"
# Default for Login to Target
result=( "TestName" "TestIP" "TestServerIP" "TestProtokoll" "TestPort" "TestPath" )
file_convert="/opt/prepare/convert_script"
for ((i=0; i <=5; i++)); do
echo "$i"
echo '${result['"$i"']}='"${result[$i]}"
done
cp /opt/apache/current/conf/appadmin/examples/$target_file /tmp
while read line; do
if [ "$(cut -d, -f1 <<< $line)" == "$target_file" ]; then
echo $line
this=$(cut -d, -f2 <<< ${line})
echo ${this}
echo "sed -i $this /tmp/$target_file"
sed -i "$this" /tmp/$target_file
fi
done < $file_convert
#cat /tmp/$target_file
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Ehrlich gesagt verstehe ich nicht, was Dein Skript überhaupt macht oder machen soll. - das wirbelt da irgendwas mit einem Apache-Webserver herum ... Und wofür brauchst Du hier eine Variable-aufgerufen-durch-eine-Variable (also eine assoziative Variable) ? - das mach alles nur unnötig kompliziert und im Falle von eval auch unsicher. Du wolltest doch noch immer die Ersetzungen für sed (oder Vergleichbares) auslagern in eine eigene Datei, richtig ? Wie das unmittelbar mit sed möglich ist, das hatte ich in meinem vorigen Post schon gezeigt. Wenn Dir das zu windig ist, und Du lieber nur mit den Mitteln der Shell arbeitest, dann geht das ganz ähnlich:
Du liest eine Zeile aus Deiner Listendatei Du verfütterst sie an den Ersetzungs-Befehl (egal ob das nun sed ist oder eine Parameter-Expansion)
Wenn Du möchtest, zeige ich Dir auch ein Beispiel nur mit der Shell, mit zwei read -Schleifen und einer P-E-Ersetzung. Damit geht das genauso gut. Aber im Moment ist mir nicht ganz klar, was Du genau willst. LG, track
|
Sonie
(Themenstarter)
Anmeldungsdatum: 1. Mai 2012
Beiträge: 133
Wohnort: Höchst im Odenwald
|
Ich habe mein Problem soweit eingegrenzt, dass ich es jetzt hier so erklären kann: Nur Variable in Variable wird geparst
| result=( "TestName" "TestIP" )
res='result[1]'
echo "${res}"
echo "${!res}"
|
ergibt
result[1]
testIP Variable mit Text in Variable wird nicht gefunden
| result=( "TestName" "TestIP" )
res='Text davor result[1] Text danach'
echo "${res}"
echo "${!res}"
|
ergibt
Text davor result[1] Text danach
(leere Zeile)
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
Ich möchte noch anmerken, dass das einzelne Aufrufen von sed mit jeweils nur einer Ersetzung extrem ineffizient ist, insbesondere, da es ja wohl "so viele" Ersetzungspaare sind. Alle Ansätze, die ein sed -Skript erzeugen und das dann an sed verfüttern, sind da zu bevorzugen.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Komisch, bei mir geht es: track@track:~$ result=( "TestName" "TestIP" )
track@track:~$ res='result[1]'
track@track:~$ echo "${res}"
result[1]
track@track:~$ echo "${!res}"
TestIP Könnte es sein, dass Du eine andere Shell als die Bash benutzt ? track (ich bin erst heute Abend wieder da, muss erstmal arbeiten ...)
|
Sonie
(Themenstarter)
Anmeldungsdatum: 1. Mai 2012
Beiträge: 133
Wohnort: Höchst im Odenwald
|
rklm schrieb: Ich möchte noch anmerken, dass das einzelne Aufrufen von sed mit jeweils nur einer Ersetzung extrem ineffizient ist, insbesondere, da es ja wohl "so viele" Ersetzungspaare sind. Alle Ansätze, die ein sed -Skript erzeugen und das dann an sed verfüttern, sind da zu bevorzugen.
möchte ich ja, dumm nur, dass die zu ersetzenden inhalte auch erst zur laufzeit bekannt werden, daher suche ich nach einer Möglichkeit, aus den unbekannten Variablen eine SED-Anweisung zu bauen, die ich dann mittels -f übergebe
|
Sonie
(Themenstarter)
Anmeldungsdatum: 1. Mai 2012
Beiträge: 133
Wohnort: Höchst im Odenwald
|
track schrieb: Komisch, bei mir geht es: track@track:~$ result=( "TestName" "TestIP" )
track@track:~$ res='result[1]'
track@track:~$ echo "${res}"
result[1]
track@track:~$ echo "${!res}"
TestIP Könnte es sein, dass Du eine andere Shell als die Bash benutzt ? track (ich bin erst heute Abend wieder da, muss erstmal arbeiten ...)
sagte ich ja, probier das bitte mit "text vor der zu ersetzenden Variable",
res='Text davor result[1] Text danach' ist nur eine vermutung...
wenn ich es richtig verstehe, gibt es zwei verschiedene typen von Strings; einfaches und doppeltes hochkomma...
res1='test/${result[0]}/g'
res2="test/${result[0]}/g"
res1 wird aufgelöst, res2 nicht, gibt es eine Möglichkeit Strings vom Typ res1 nach Typ res2 umzuwandeln?
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
Sonie schrieb: rklm schrieb: Ich möchte noch anmerken, dass das einzelne Aufrufen von sed mit jeweils nur einer Ersetzung extrem ineffizient ist, insbesondere, da es ja wohl "so viele" Ersetzungspaare sind. Alle Ansätze, die ein sed -Skript erzeugen und das dann an sed verfüttern, sind da zu bevorzugen.
möchte ich ja, dumm nur, dass die zu ersetzenden inhalte auch erst zur laufzeit bekannt werden,
Deshalb kannst Du doch trotzdem ein Skript für sed erzeugen, anstatt es ständig mit nur einer Ersetzung auszuführen. Wo kommen die Ersetzungspaare denn her?
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
Sonie schrieb:
wenn ich es richtig verstehe, gibt es zwei verschiedene typen von Strings; einfaches und doppeltes hochkomma...
Genauer sind das zwei Arten Strings zu erzeugen. Das ist ein Unterschied.
res1='test/${result[0]}/g'
res2="test/${result[0]}/g"
res1 wird aufgelöst, res2 nicht, gibt es eine Möglichkeit Strings vom Typ res1 nach Typ res2 umzuwandeln?
So funktioniert das nicht. Das Quoting bestimmt, welcher String als Ergebnis herauskommt. Da gibt es hinterher nix umzuwandeln, weil es nur einen Typ Zeichenketten gibt. Hier fehlen noch ganz viele Informationen, habe ich den Eindruck. Z.B.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Sonie schrieb: ... probier das bitte mit "text vor der zu ersetzenden Variable",
res='Text davor result[1] Text danach'
Wieso sollte da auch irgendwas mit der Variablen ${result[1]} heraus kommen ?? - diese Variable kommt doch dort überhaupt nicht vor ! Nirgends. Du solltest vielleicht doch mal verraten, was Du tatsächlich machen willst, vom Kontext her. Im Moment bist Du nur wild am probieren und wunderst Dich, dass da keine sinnvollen Ergebnisse rauskommen ... track
|
Sonie
(Themenstarter)
Anmeldungsdatum: 1. Mai 2012
Beiträge: 133
Wohnort: Höchst im Odenwald
|
track schrieb: Sonie schrieb: ... probier das bitte mit "text vor der zu ersetzenden Variable",
res='Text davor result[1] Text danach'
Wieso sollte da auch irgendwas mit der Variablen ${result[1]} heraus kommen ?? - diese Variable kommt doch dort überhaupt nicht vor ! Nirgends. Du solltest vielleicht doch mal verraten, was Du tatsächlich machen willst, vom Kontext her. Im Moment bist Du nur wild am probieren und wunderst Dich, dass da keine sinnvollen Ergebnisse rauskommen ... track
natürlich habe ich eine variable result definiert, diese kommt auch aus einer datei... und wird zeilenweise eingelesen.
result=( "hostname" "hostip" "port" "protokoll" "virtip" "anything" )
daraus soll dann je virtuellen pc eine config datei für einen apache erstellt werden. mea culpa, bin davon ausgegangen, dass dies offensichtlich war.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Sonie schrieb: natürlich habe ich eine variable result definiert, diese kommt auch aus einer datei... und wird zeilenweise eingelesen.
result=( "hostname" "hostip" "port" "protokoll" "virtip" "anything" )
Nee, da irrst Du ! - was Du da machst: Du füllst ein Array mit 6 Worten. Und an diese einzelnen Array-Felder kommst Du eben auch nur genau mit den entsprechenden Array-Ausdrücken ${result[0]} ... ${result[5] } heran, und nicht mit mit einem nackten Wort, an das Du einen Index [1] anhängst. Du musst die Bash-Syntax schon so nehmen, wie sie ist. Guck Dir doch einfach an, was Du der Shell als Befehlszeile anbietest: ${Text davor result[1] Text danach} Wie soll die arme Bash darin jemals die Variable ${result[1]} erkennen ? track
|