Ich habe eine Situation, in der ein Bash-Skript eine ganze Zeile in einer Datei ersetzen soll. Die Zeilennummer ist immer dieselbe, so dass es sich um eine fest codierte Variable handeln kann.
Ich versuche nicht, eine Unterzeichenfolge in dieser Zeile zu ersetzen, sondern möchte diese Zeile nur vollständig durch eine neue Zeile ersetzen.
Gibt es dafür Bash-Methoden (oder etwas Einfaches, das in ein .sh-Skript geworfen werden kann)?
sed: -e expression #1, char 26: unknown option to ``s'
und meine Linie ist :sed -i '7s/.*/<param-value>http://localhost:8080/ASDF/services/REWS.REWSHttpSoap12Endpoint/</param-value>/' $TCE_SVN_HOME\trunk\tce\EWC\WebContent\WEB-INF\web.xml
. Irgendeine Idee?/
im Ersetzungstext wird als abschließender Schrägstrich dess
Befehls interpretiert, sofern nicht maskiert (\/
). Am einfachsten ist es jedoch, ein anderes, nicht verwendetes Zeichen als Trennzeichen auszuwählen. Zum Beispielsed -i '7s{.*}{<param-value>http://...}' $TCE_SVN_HOME/trunk...
.s
bestimmt das Trennzeichen.#
sed -i '7s#.*#<param-value>http://localhost:8080/ASDF/services/REWS.REWSHttpSoap12Endpoint/</param-value>#'
-e
if-i
. Somit wird der richtige Befehl:sed -e 'Ns/.*/replacement-line/' -i '' file.txt
Ich habe dieses Skript tatsächlich verwendet, um vor einiger Zeit eine Codezeile in der Cron-Datei auf den UNIX-Servern unseres Unternehmens zu ersetzen. Wir haben es als normales Shell-Skript ausgeführt und hatten keine Probleme:
Dies erfolgt nicht nach Zeilennummer, aber Sie können einfach zu einem auf Zeilennummern basierenden System wechseln, indem Sie die Zeilennummer vor das setzen
s/
und einen Platzhalter anstelle von setzenthe_original_line
.quelle
sed -e "s/.../.../" /dir/file > /dir/temp_file
sed -e "s/.../.../" /dir/file > /dir/file
Angenommen, Sie möchten Zeile 4 durch den Text "different" ersetzen. Sie können AWK wie folgt verwenden:
AWK betrachtet die Eingabe als "Datensätze", die in "Felder" unterteilt sind. Standardmäßig ist eine Zeile ein Datensatz.
NR
ist die Anzahl der gesehenen Datensätze.$0
stellt den aktuellen vollständigen Datensatz dar (während dies$1
das erste Feld aus dem Datensatz usw. ist; standardmäßig sind die Felder Wörter aus der Zeile).Wenn die aktuelle Zeilennummer 4 ist, drucken Sie die Zeichenfolge "anders", andernfalls drucken Sie die Zeile unverändert.
In AWK wird der in eingeschlossene Programmcode
{ }
einmal in jedem Eingabedatensatz ausgeführt.Sie müssen das AWK-Programm in einfache Anführungszeichen setzen, damit die Shell nicht versucht, Dinge wie das zu interpretieren
$0
.EDIT: Ein kürzeres und eleganteres AWK-Programm von @chepner in den Kommentaren unten:
Ersetzen Sie nur für Datensatz (dh Zeile) Nummer 4 den gesamten Datensatz durch die Zeichenfolge "different". Drucken Sie dann für jeden Eingabedatensatz den Datensatz.
Offensichtlich sind meine AWK-Fähigkeiten verrostet! Vielen Dank, @chepner.
EDIT: und siehe auch eine noch kürzere Version von @Dennis Williamson:
Wie dies funktioniert, wird in den Kommentaren erklärt: Der
1
Wert wird immer als wahr ausgewertet, sodass der zugehörige Codeblock immer ausgeführt wird. Es ist jedoch kein Codeblock zugeordnet, was bedeutet, dass AWK standardmäßig nur die gesamte Zeile druckt. AWK wurde entwickelt, um knappe Programme wie dieses zu ermöglichen.quelle
awk 'NR==4 {$0="different"} { print }' input_file.txt
.awk 'NR==4 {$0="different"}1' input_file.txt
1
? (Hinweis: Ich habe es getestet und es funktioniert tatsächlich! Ich verstehe nur nicht wie.)Angesichts dieser Testdatei (test.txt)
Der folgende Befehl ersetzt die erste Zeile durch "Zeilenumbruch".
Ergebnis:
Weitere Informationen finden Sie hier
http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/
quelle
sed '1 cnewline text' test.txt
würde es auch tun.Ersetzen Sie in bash N, M durch die Zeilennummern und xxx yyy durch das, was Sie möchten
BEARBEITEN
Tatsächlich gibt es bei dieser Lösung einige Probleme mit den Zeichen "\ 0" "\ t" und "\".
"\ t" kann gelöst werden, indem IFS = vor dem Lesen gesetzt wird: "\" am Ende der Zeile mit -r
Für "\ 0" wird die Variable jedoch abgeschnitten. In Pure Bash gibt es keine Lösung: Weisen Sie einer Variablen in Bash eine Zeichenfolge mit einem Nullzeichen (\ 0) zu. In einer normalen Textdatei gibt es jedoch kein Nullzeichen \ 0
Perl wäre eine bessere Wahl
quelle
quelle
Hervorragende Antwort von Chepner. Es funktioniert für mich in Bash Shell.
hier
index
- Zeile Nr.newLine
- neue Zeilenfolge, die wir ersetzen möchten.In ähnlicher Weise wird der folgende Code verwendet, um eine bestimmte Zeile in der Datei zu lesen. Dies hat keine Auswirkungen auf die eigentliche Datei.
hier
!d
- löscht die anderen Zeilen als Zeile no.$index
Wir erhalten also die Ausgabe als Zeilenzeichenfolge no$index
in der Datei.quelle
${newline}
?Auf dem Mac habe ich verwendet
quelle
Sie können sogar Parameter an den Befehl sed übergeben:
test.sh
orignial output.dat:
Die Ausführung ./test.sh gibt die neuen OUTPUT.DAT
quelle
line=5; sed -i "${line}s/.*/replaced by '$i'!/" output.dat