Antworten:
sed -i 's/original/new/g' file.txt
Erläuterung:
sed
= Stream-Editor-i
= an Ort und Stelle (dh in die ursprüngliche Datei zurückspeichern)Die Befehlszeichenfolge:
s
= der Ersatzbefehloriginal
= ein regulärer Ausdruck, der das zu ersetzende Wort beschreibt (oder nur das Wort selbst)new
= der zu ersetzende Textg
= global (dh alles ersetzen und nicht nur das erste Vorkommen)file.txt
= der Dateiname
sed
werden diese mit diesen übereinstimmen. Fügen Sie ein -r
Flag hinzu, wenn Sie stattdessen erweiterte REs verwenden möchten.
/
Zeichen handelt, mit dem Sie übereinstimmen müssen, können Sie einfach ein anderes Zeichen als Trennzeichen verwenden (z 's_old/text_new/text_g'
. B. ). Andernfalls können Sie ein \
vor ein beliebiges setzen $ * . [ \ ^
, um das Literalzeichen zu erhalten.
sed -i '.bak' 's/original/new/g' file.txt
kann auch mit einer Erweiterung sed -i '' 's/original/new/g' file.txt
der Länge 0 ausgeführt werden , wodurch keine Sicherung generiert wird.
Hierfür gibt es verschiedene Möglichkeiten. Man benutzt sed
und Regex. SED ist ein Stream-Editor zum Filtern und Transformieren von Text. Ein Beispiel ist wie folgt:
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog
Ein anderer Weg, der sinnvoller sein kann als < strin
und > strout
ist mit Rohren!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai
The quick brown fox jumped over the lazy sleeping dog
cat
in cat file | sed '...'
ist nicht erforderlich. Sie können direkt sagen sed '...' file
.
sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly
Datei wird in regelmäßigen Abständen abgelegt und die 2 Änderungen werden an Ort und Stelle vorgenommen, während ein Backup erstellt wird. Mit time bash -c "$COMMAND"
der Zeit lässt sich sagen, dass diese Version ~ 5-mal schneller ist.
Es gibt eine Vielzahl von Möglichkeiten, dies zu erreichen. Abhängig von der Komplexität dessen, was mit dem Ersetzen von Zeichenfolgen erreicht werden soll, und abhängig von den Tools, mit denen der Benutzer vertraut ist, werden einige Methoden möglicherweise mehr bevorzugt als andere.
In dieser Antwort verwende ich eine einfache input.txt
Datei, mit der Sie alle hier aufgeführten Beispiele testen können. Der Inhalt der Datei:
roses are red , violets are blue
This is an input.txt and this doesn't rhyme
Bash ist eigentlich nicht für die Textverarbeitung gedacht, aber einfache Ersetzungen können durch Parametererweiterung erfolgen , insbesondere können wir hier eine einfache Struktur verwenden ${parameter/old_string/new_string}
.
#!/bin/bash
while IFS= read -r line
do
case "$line" in
*blue*) printf "%s\n" "${line/blue/azure}" ;;
*) printf "%s\n" "$line" ;;
esac
done < input.txt
Dieses kleine Skript ersetzt nicht direkt, dh Sie müssten neuen Text in einer neuen Datei speichern und die alte Datei entfernen oder mv new.txt old.txt
Randbemerkung: Wenn Sie neugierig sind , warum while IFS= read -r ; do ... done < input.txt
verwendet wird, ist es im Grunde Art und Weise Shell die Datei Zeile für Zeile zu lesen. Siehe dies als Referenz.
AWK, ein Textverarbeitungsprogramm, ist für eine solche Aufgabe durchaus geeignet. Es kann einfache und fortgeschrittene Ersetzungen auf der Basis regulärer Ausdrücke durchführen . Es bietet zwei Funktionen: sub()
und gsub()
. Der erste ersetzt nur das erste Vorkommen, während der zweite - Vorkommen in der gesamten Zeichenfolge ersetzt. Wenn wir zum Beispiel einen String haben one potato two potato
, wäre dies das Ergebnis:
$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana
$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'
one banana two potato
AWK kann eine Eingabedatei als Argument verwenden. Dasselbe input.txt
gilt für:
awk '{sub(/blue/,"azure")}1' input.txt
Abhängig von der Version von AWK, die Sie haben, kann es sein, dass die Bearbeitung an Ort und Stelle erfolgt oder nicht. Daher besteht die übliche Praxis darin, neuen Text zu speichern und zu ersetzen. Zum Beispiel so etwas:
awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt
Sed ist ein Zeileneditor. Es werden auch reguläre Ausdrücke verwendet, aber für einfache Ersetzungen ist es ausreichend, Folgendes zu tun:
sed 's/blue/azure/' input.txt
Das Gute an diesem Tool ist, dass es eine direkte Bearbeitung hat, die Sie mit -i
flag aktivieren können .
Perl ist ein weiteres Tool, das häufig für die Textverarbeitung verwendet wird, aber eine universelle Sprache ist und in Netzwerken, der Systemadministration, Desktop-Apps und vielen anderen Bereichen verwendet wird. Es wurden viele Konzepte / Funktionen aus anderen Sprachen wie C, sed, awk und anderen übernommen. Eine einfache Ersetzung kann folgendermaßen erfolgen:
perl -pe 's/blue/azure/' input.txt
Wie sed hat auch perl das Flag -i.
Diese Sprache ist sehr vielseitig und wird auch in einer Vielzahl von Anwendungen verwendet. Es hat eine Menge Funktionen für die Arbeit mit Strings, unter denen Sie replace()
, wenn Sie Variablen wie haben var="Hello World"
, tun könntenvar.replace("Hello","Good Morning")
Ein einfacher Weg, eine Datei zu lesen und einen String darin zu ersetzen, wäre folgender:
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
Mit Python müssen Sie jedoch auch in eine neue Datei ausgeben, was Sie auch innerhalb des Skripts selbst tun können. Zum Beispiel ist hier ein einfacher:
#!/usr/bin/env python
import sys
import os
import tempfile
tmp=tempfile.mkstemp()
with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
for line in fd1:
line = line.replace('blue','azure')
fd2.write(line)
os.rename(tmp[1],sys.argv[1])
Dieses Skript ist input.txt
als Kommandozeilenargument aufzurufen. Der genaue Befehl zum Ausführen eines Python-Skripts mit einem Befehlszeilenargument wäre
$ ./myscript.py input.txt
oder
$ python ./myscript.py input.txt
Vergewissern Sie sich natürlich, dass ./myscript.py
sich das in Ihrem aktuellen Arbeitsverzeichnis befindet, und stellen Sie zunächst sicher, dass es mit ausführbar eingestellt istchmod +x ./myscript.py
Python kann auch reguläre Ausdrücke haben, insbesondere gibt es re
Module, die re.sub()
Funktionen haben, die für fortgeschrittenere Ersetzungen verwendet werden können.
tr
Befehls in Unix
tr
ist ein weiteres großartiges Werkzeug, aber beachten Sie, dass es für den Ersatz Zeichensätze (zum Beispiel tr abc cde
würde übersetzen a
zu c
, b
bis d
es ein bisschen anders ist zu ersetzen ganze Wörter wie mit. sed
Oderpython
Sie können Vim im Ex-Modus verwenden:
ex -s -c '%s/OLD/NEW/g|x' file
%
Wählen Sie alle Zeilen aus
s
Ersatz
g
Ersetzen Sie alle Instanzen in jeder Zeile
x
schreiben Sie, wenn Änderungen vorgenommen wurden (sie haben) und beenden Sie
Durch awks gsub Befehl
awk '{gsub(/pattern/,"replacement")}' file
Beispiel:
awk '{gsub(/1/,"0");}' file
Im obigen Beispiel werden alle Einsen durch Nullen ersetzt, unabhängig von der Spalte, in der sie sich befinden.
Wenn Sie eine bestimmte Spalte ersetzen möchten, gehen Sie folgendermaßen vor:
awk '{gsub(/pattern/,"replacement",column_number)}' file
Beispiel:
awk '{gsub(/1/,"0",$1);}' file
Ersetzt 1 nur in der ersten Spalte durch 0.
Durch Perl,
$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
inotifywait
unter sh
env an und berichte Daten im CSV-Format (da das benutzerdefinierte Format fehlerhaft ist). Ich dachte mir dann, dass es keine einfache Möglichkeit gibt, CSV-Dokumente in Shell-Skripten zu verarbeiten ... Und ich möchte, dass es sehr leicht ist. Also habe ich ein ziemlich einfaches Skript gestartet, um CSV zu analysieren und zu melden. Ich habe die CSV-Spezifikation gelesen und festgestellt, dass sie ausgefeilter ist als erwartet, und dass sie in doppelte Anführungszeichen eingeschlossene mehrzeilige Werte unterstützt. sed
Bei der Tokenisierung habe ich mich darauf verlassen, aber bald wurde mir klar, dass selbst bei sed
Multilines bis zu zwei Leitungen möglich sind. Was ist, wenn einer meiner CSV-Werte mehr als zwei Zeilen umfasst?
sed
ist die s tream ed itor , in die Sie verwenden können |
(Rohr) zu senden Standard - Streams (STDIN und STDOUT spezifisch) durch sed
und verändern sie im Fluge programmatisch, es ist ein praktisches Tool , in der Philosophie , Tradition Unix zu machen; Sie können Dateien jedoch auch direkt bearbeiten, indem Sie den -i
unten angegebenen Parameter verwenden.
Beachten Sie Folgendes :
sed -i -e 's/few/asd/g' hello.txt
s/
wird verwendet s ubstitute den gefundenen Ausdruck few
mit asd
:
Die Wenigen, die Tapferen.
Der Asd, der Tapfere.
/g
steht für "global" und bedeutet dies für die gesamte Zeile. Wenn Sie das /g
(mit s/few/asd/
, es muss immer drei Schrägstriche geben, egal was passiert) weglassen und few
zweimal in derselben Zeile erscheinen, wird nur die erste few
geändert in asd
:
Die wenigen Männer, die wenigen Frauen, die Mutigen.
Die Männer, die wenigen Frauen, die Mutigen.
Dies ist unter bestimmten Umständen hilfreich, z. B. beim Ändern von Sonderzeichen am Anfang von Zeilen (z. B. durch Ersetzen der Größer-als-Symbole, mit denen manche Benutzer vorheriges Material in E-Mail-Threads mit einem horizontalen Tabulator zitieren, während später in der Zeile eine zitierte algebraische Ungleichung verbleibt unberührt), aber in Ihrem Beispiel, in dem Sie angeben, dass überall , wo esfew
vorkommt, es ersetzt werden soll, stellen Sie sicher, dass Sie das haben /g
.
Die folgenden zwei Optionen (Flags) werden zu einer zusammengefasst -ie
:
-i
Option wird verwendet , um zu bearbeiten i n auf die Datei platzieren hello.txt
.
-e
Option gibt die e xpression / Befehl ausgeführt werden soll, in diesem Fall s/
.
Hinweis: Es ist wichtig, dass Sie -i -e
zum Suchen / Ersetzen verwenden. In diesem -ie
Fall erstellen Sie eine Sicherungskopie jeder Datei, an die der Buchstabe "e" angehängt ist.
Das können Sie machen:
locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g"
Beispiele: Um alle Vorkommen [logdir ',' '] (ohne []) durch [logdir', os.getcwd ()] in allen Dateien zu ersetzen, die das Ergebnis des Befehls locate sind, gehen Sie wie folgt vor:
ex1:
locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"
ex2:
locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"
Wobei [tensorboard / program.py] die zu durchsuchende Datei ist
logdir', ''
-> /logdir', os.getcwd()
) macht es schwierig, diese Antwort zu analysieren. Außerdem sollte angegeben werden, dass Ihre Antwort zuerst die zu verwendenden Dateien findet, da dies nicht Teil der Frage ist.