sed: Wie kann man die variable Zeile ersetzen, wenn sie gefunden wird, oder an das Ende der Datei anhängen, wenn sie nicht gefunden wird?

545
Wade S

Meine Frage basiert also weitgehend auf einer verwandten Frage, hat aber einen wesentlichen Unterschied.

In der Antwort von:

sed '/^FOOBAR=/;$;x}' infile 

Ich habe eine Variation gemacht, die FOOBAR zu einer Variablen macht (z. B. den Namen eines Programms und dann eine for-Schleife, um eine Liste von Programmen und deren Installationsstatus zu erstellen). Dies ist für ein ziemlich engagiertes Projekt, an dem ich gerade arbeite, um die Installation von Drawile for Raspberry Pi mit einigen neuen Funktionen zu vereinfachen, aber das ist eine andere Art von Würmern, auf die ich mich nicht werde.

sed -i '/^'"$FOOBAR"'=/;$;x}' infile 

Ich möchte, dass newvalue eine $ -Variable ist, die sich im Skript ändern kann. Ich kann einfach nicht herausfinden, wie ich das schaffen kann, einfach mit "und" nicht richtig machen. Ich habe stundenlang gesucht und versucht, Tutorials zu lesen, aber ich verstehe nicht genug und bin sehr tief getaucht In die inneren Funktionen von sed. Meistens wird diese Variable etwas einfaches sein wie: Ja, Nein oder Fehler, aber ich könnte sie auch verwenden, um Ordner- und Dateipfade darzustellen ... also mache ich mir Sorgen um / Substitutionen auch hier: Auch wenn es keine vollständige Antwort ist, bin ich froh, es selbst herauszufinden, solange ich in die Richtung weisen kann, in die ich gehen muss, um das besser zu verstehen.


Edit: Es gibt nicht viel zu posten, da es etwas Grundsätzliches gibt, das ich sicher vermisse. Ich habe gerade versucht, Anführungszeichen um newvalue zu setzen. Wie folgt ...

sed -i '/^FOOBAR=/;$;x}' infile 

Ausgabe: FOOBAR = $ newvalue Dies ist falsch. Sollte den gespeicherten Wert für newvalue ausgeben!

sed -i '/^FOOBAR=/;$;x}' infile 

Ausgabe: FOOBAR = "$ newvalue" Dies ist falsch. Sollte den gespeicherten Wert für newvalue ausgeben!

sed -i '/^FOOBAR=/;$;x}' infile 

Ausgabe: sed: -e Ausdruck # 1, Zeichen 30: unbekannte Option für `s '

Wenn newvalue gleich Yes ist, möchte ich, dass die Ausgabe "FOOBAR = Yes" oder möglicherweise ein Ordnerpfad ist.


Edit 2: Es kann wirklich alles sein, vorausgesetzt, es funktioniert einfach. Ich bin nicht besonders damit einverstanden, aber ich habe wahrscheinlich die meiste Erfahrung mit sed.


Edit 3: Die Antwort gefunden.

sed -i '\!^'"$FOOBAR"'=!;$;x}' /home/pi/Public/test.txt 
1
"einfach mit" "und" "macht es nicht richtig" - Bitte posten Sie den Befehl, der es nicht richtig macht, damit wir debuggen können. Kamil Maciorowski vor 5 Jahren 0
[Muss es "sed" sein?] (Https://en.wikipedia.org/wiki/Turing_tarpit) Mit Perl oder Awk oder sogar sorgfältig kombinierten Shell-Builds wäre das viel einfacher. grawity vor 5 Jahren 0
Die Variante mit `'" $ newvalue "' 'sollte funktionieren, denke ich, es sei denn, $ newvalue` ändert `sed`-Logik. Wenn es beispielsweise `/` enthält, wählen Sie einen anderen Buchstaben als Trennzeichen für `sed`. `sed 's / a / b /'` kann `sed 's | a | b |'` oder sogar `sed 'sRaRbR' 'sein. Wähle einen Charakter, der nicht mit dem möglichen $ newvalue kollidiert. Kamil Maciorowski vor 5 Jahren 1
Es tut nicht Es gibt $ newvalue und nicht den in der Variablen gespeicherten Wert aus. Dies ist nicht die gewünschte Ausgabe. Wade S vor 5 Jahren 0
Ich spreche von der Variante, die Ihnen eine unbekannte Option für 's' gibt. Versuchen Sie es mit `$ newvalue`, das nicht` / `enthält. Kamil Maciorowski vor 5 Jahren 0
Anstatt einfache und doppelte Anführungszeichen zu mischen, würde ich vorschlagen, dass es einfacher ist, die ursprüngliche Ersetzung nur mit doppelten Anführungszeichen zu verwenden und (\ "\") die Zeilenende- / letzten Zeilenverweise zu umgehen: `sed" / ^ $ FOOBAR = / ; \ $ ; x} "`. Beachten Sie jedoch @ KamilMaciorowskis Kommentar zu `/` in `$ newvalue`. Dies bedeutet, dass Sie möglicherweise das Trennzeichen ändern müssen. AFH vor 5 Jahren 0
Ich bekomme nur neue Probleme, wenn ich das tue (* sed: -e Ausdruck # 1, Zeichen 1: unbekannter Befehl: `| '*). Ich habe versucht, den Begrenzer ohne Erfolg auszutauschen. Und einfach die Auswahl einer Option, die nicht enthält / ist, ist in Anbetracht dessen, was ich versuche, das Skript dazu zu bringen, nicht wirklich eine Option. Wade S vor 5 Jahren 0
Wenn Sie ein anderes Trennzeichen in der Adresse verwenden, müssen Sie das erste Trennzeichen `sed \ | ^ FOOBAR = | ... etc 'deaktivieren. In `s`-Befehl wird keine Flucht benötigt. Paulo vor 5 Jahren 0
Ah, ich glaube, ich habe eine Lösung gefunden, in der mich jeder mit seiner Hilfe hinführt. Das schätze ich aufrichtig. `sed -i '\! ^'" $ FOOBAR "'=! ; $ ; x}' / home / pi / Public / test.txt` Wade S vor 5 Jahren 0
Die Antwort sollte als Antwort gepostet werden. Siehe [Kann ich meine eigene Frage beantworten?] (Https://superuser.com/help/self-answer). Der einzige Befehl (ohne Erklärung, was das Problem wirklich war und was der Fix genau macht) wäre eine ziemlich schlechte Antwort obwohl. Kamil Maciorowski vor 5 Jahren 0
Ich habe vor, das zu tun, aber ich werde jetzt ungefähr sechs Stunden schlafen, bevor ich zur Arbeit gehe. Die richtige Beschreibung jedes Teils, was er tut und warum er ausgeführt wurde, wird etwas mehr Zeit in Anspruch nehmen, als ich jetzt geben kann. Ich habe nur versucht herauszufinden, ob ich heute Nacht so weit sein könnte, dass ich es lösen könnte oder mehr Input für das Problem benötige. Wade S vor 5 Jahren 0
Wenn Sie es richtig machen, hinterlassen Sie mir bitte einen Kommentar unter der Frage, beginnend mit @KamilMaciorowski. Wenn Ihre Erklärung dann sinnvoll ist, werde ich die Antwort gerne aufgreifen. Kamil Maciorowski vor 5 Jahren 0

0 Antworten auf die Frage