2017-12-31 64 views
-1

ich einige Konfigurationsdatei wie Beispiel habenParameterwert Ersetzen sed oder awk mit

A_place = 10km 
B_place=5km 
#A_place=2km 
C_place=1km 

ich den A_place Wert in der uncommented Linie ändern möchten. Einige der Linien können Anfangsräume haben. Ich habe versucht, einen grundlegenden sed Befehl zu finden und zu ersetzen, aber es hat nicht funktioniert. Vielleicht sollte ich AWK statt Stream-Editor verwenden?

+4

Warum Sie C Tag haben? Bitte posten Sie die 'sed' Befehle, die Sie ausprobiert haben. Veröffentlichen Sie auch das Ergebnis, das Sie erhalten haben und was Sie wollten. – kabanus

+2

Angesichts der fehlenden Genauigkeit in der Frage wäre eine sinnvolle Antwort "Verwenden Sie den richtigen sed-Befehl". –

+2

Bitte fügen Sie Ihre gewünschte Ausgabe für diese Beispieleingabe zu Ihrer Frage hinzu. – Cyrus

Antwort

1

mit sed:

sed -e '/#/!s/\(A_place[[:space:]]*=[[:space:]]*\)\(.*\)/\1"new_value"/' input

Zusammenbruch von dem, was hier getan wird:

l überspringen

ines das sind Kommentare:

/# /!

Dann kommt die Substitution in Form

s/alt/neu/

die alten auswählen, und legen Sie die Original-Zeichenkette innerhalb Pars (Rückreferenzierung), so dass es später zurückgehalten werden kann durch Spezifizieren \ 1. Dies entspricht der Zeichenkette "A_place", gefolgt von null oder mehr Leerzeichen Zeichen, gefolgt von dem Gleichheitszeichen gefolgt von Null mehr mehr Leerzeichen Zeichen. Beachten Sie, dass der zu ersetzende Wert ebenfalls in Parens liegt und mit \ 2; Es wird hier nicht benötigt und die Parens können weggelassen werden. So ist die alte Zeichenfolge übereinstimmen ist:

( A_place [[: space:]] * = [[: space:]] * ) (. *)

Dann wird die neue Zeile Ausgang wird mit dem Backref "\ 1" erstellt, wobei der Leerraum um das Gleichheitszeichen erhalten bleibt und der "neue Wert" angefügt wird, hier zur besseren Anschaulichkeit in Anführungszeichen, die in der neuen Zeile zwar Literal sind, aber in der endgültigen Ausgabe wahrscheinlich nicht erwünscht sind.„\ 1“ hier ist alles, was in den ersten paren begrenzt regex abgestimmt wurde, einschließlich Leerzeichen um das Gleichheitszeichen:

\ 1 „new_value“

0

Folgende awk kann Ihnen helfen, in der gleichen.

awk '!/#/{sub(/A_place/,"new_value")} 1' Input_file 

oder bei OP will die A_place Zeichenfolge der letzten Spalte Wert dann verwenden, um ändern:

awk '!/#/ && /A_place/{$NF="new_value"} 1' Input_file 

Falls Sie mehr als 1 Vorkommen dann sub-gsub ändern A_place Zeichenfolge haben . Wenn Sie die Ausgabe in derselben Eingabedatei speichern möchten, können Sie auch den folgenden Code für dieselbe verwenden.

awk '!/#/{sub(/A_place/,"new_value")} 1' Input_file > temp_file && mv temp_file Input_file 

ODER

awk '!/#/ && /A_place/{$NF="new_value"} 1' Input_file > temp_file && mv temp_file Input_file 
+2

Dies ersetzt "A_place" durch "new value", aber ich denke, das OP möchte 'A_place =' behalten und den Abstand ändern. –

+0

@MOehm, danke, ich habe diese Lösung jetzt auch in meinem Beitrag hinzugefügt. – RavinderSingh13

+1

Ja, aber Ihre neue Variante funktioniert nicht, wenn um das Gleichheitszeichen herum keine Leerzeichen stehen. (Die 'A_place' enthält sie nicht, aber die anderen Zeilen machen deutlich, dass dies eine gültige Syntax ist. Sie könnten aber auch das' = 'Feldtrennzeichen machen.) –

0

Der folgende sed Ausdruck wird die neue Strecke von A_place auf 32 km. Die Räume der alles bis zur neuen Strecke bleiben erhalten:

> cat kk.config 
A_place = 10km 
B_place=5km 
#A_place=2km 
C_place=1km 

> sed -i -e 's/^\(*A_place *= *\).*/\132km/' kk.config 

> cat kk.config 
A_place = 32km 
B_place=5km 
#A_place=2km 
C_place=1km 

Eines der Probleme mit regulären Ausdrücken ist, dass es so viele Aromen. Anscheinend verwendet sed grundlegende Regexes, und Sie müssen die umgekehrten Schrägstriche in die Klammern setzen, wenn Sie Elemente für spätere Rückverweise gruppieren möchten. Der Caret fängt am Anfang der Zeile an und ignoriert daher das Match in Kommentaren.

0

Eine generische Lösung kann mit awk geschehen, wenn wir ein paar Dinge übernehmen:

  1. Leer um = immer entfernt werden kann
  2. Wir für eine genaue Übereinstimmung auf der linken Seite suchen
  3. Schlüsselwerte bestehen aus einem einzigen Wort unquoted

dies mit uns einen kleinen Shell-Wrapper run.sh wit erstellen h der Schlüssel und Wert als Parameter:

key=$1 
value=$2 
awk -F '[ =]*' \ 
    -v key=$key \ 
    -v value=$value \ 
'/^#/ { print; next } 
$1 == key { $2 = value } 
    { print $1 "=" $2 }' sample.txt 

Beispiel laufen:

$ sh run.sh A_place 20km 
A_place=20km 
B_place=5km 
#A_place=2km 
C_place=1km 
0

Einfache sed Lösung:

val="2km" 
sed "/^[[:blank:]]*A_place[[:blank:]]*=/s/=.*/= ${val}/" file 
Verwandte Themen