Originaldatei
claudio
antonio
claudio
michele
Ich möchte nur das erste Vorkommen von "claudio" mit "claudia" ändern, damit die Datei das Ergebnis liefert
claudia
antonio
claudio
michele
Ich habe versucht
sed -e '1,/claudio/s/claudio/claudia/' nomi
Aber führen Sie eine globale Substitution durch. Warum?
info sed
: (0,/REGEXP/
: Eine Zeilennummer 0 kann wie in einer Adressangabe verwendet werden ,0,/REGEXP/
so dasssed
versucht wird REGEXP in der ersten Eingangsleitung paßt auch mit anderen Worten.0,/REGEXP/
Ist Ähnlich1,/REGEXP/
, außer dass, wenn ADDR2 mit der allerersten Eingabezeile übereinstimmt, das Formular 0 / REGEXP / das Ende des Bereichs berücksichtigt, wohingegen das Formular 1 / REGEXP / mit dem Beginn des Bereichs übereinstimmt und daher die Bereichsspanne festlegt bis zum zweiten Vorkommen des regulären Ausdrucks)awk '/claudio/ && !ok { sub(/claudio/,"claudia"); ok=1 } 1' nomi
sollte tunAntworten:
Wenn Sie GNU benutzen
sed
, versuchen Sie:sed
Startet die Suche nach dem regulären Ausdruck, der einen Bereich beendet, erst nach der Zeile, die diesen Bereich beginnt.Von
man sed
(POSIX-Manpage, Hervorhebung von mir):Verwenden
awk
Bereiche in der
awk
Arbeit mehr als Sie erwartet hatten:Erläuterung:
NR==1,/claudio/
Dies ist ein Bereich, der mit Zeile 1 beginnt und mit dem ersten Auftreten von endet
claudio
.sub(/claudio/, "claudia")
Während wir uns im Bereich befinden, wird dieser Ersatzbefehl ausgeführt.
1
Die kryptische Abkürzung dieser Awk zum Drucken der Zeile.
quelle
sed
.awk '!r && /claudio/ {sub(/claudio/,"claudia"); r=1} 1'
awk !x{x=sub(/claudio/,"claudia")}1
0,/claudio/
Hier sind zwei weitere programmatische Versuche mit sed: Beide lesen die gesamte Datei in eine einzige Zeichenfolge, dann ersetzt die Suche nur die erste.
Mit Kommentar:
quelle
Eine neue Version von GNU
sed
unterstützt die-z
Option.Sie können diese Option verwenden, wenn Sie
sed
über verschiedene Zeilen arbeiten möchten .kehrt zurück
quelle
Sie können
awk
mit einem Flag feststellen , ob der Austausch bereits durchgeführt wurde. Wenn nicht, fahren Sie fort:quelle
Es ist eigentlich ganz einfach, wenn Sie nur eine kleine Verzögerung einstellen - Sie müssen nicht nach unzuverlässigen Erweiterungen greifen:
Das verschiebt nur die erste Zeile in die zweite und die zweite in die dritte und so weiter.
Es druckt:
quelle
Und noch eine Option
Der Vorteil ist, dass es doppelte Anführungszeichen verwendet, so dass Sie Variablen innerhalb verwenden können, dh.
quelle
Dies kann auch ohne den Haltebereich und ohne das Konzentrieren aller Zeilen in den Musterbereich erfolgen:
Erklärung: Wir versuchen "claudio" zu finden und springen dann in die kleine Print-Load-Schleife zwischen
:x
undbx
. Andernfalls drucken wir das Skript und starten es mit der nächsten Zeile neu.quelle
quelle
Summe
GNU-Syntax:
Oder sogar (um das zu ersetzende Wort nur einmal zu verwenden:
Oder in POSIX-Syntax:
Funktioniert auf jedem sed, verarbeitet nur so viele Zeilen wie nötig, um die erste zu finden. Funktioniert
claudio
auch, wennclaudio
sich diese in der ersten Zeile befindet und ist kürzer, da nur eine reguläre Zeichenfolge verwendet wird.Detail
Um nur eine Zeile zu ändern , müssen Sie nur eine Zeile auswählen .
Mit einem
1,/claudio/
(aus Ihrer Frage) auswählen:claudio
.Verwenden Sie zum Auswählen einer Zeile, die Folgendes enthält
claudio
:Und um nur den ersten
claudio
in der Datei auszuwählen , verwenden Sie:Dann können Sie eine Ersetzung nur in dieser Zeile vornehmen:
Dies ändert nur das erste Vorkommen der Regex-Übereinstimmung in der Zeile, auch wenn es in der ersten Zeile mehr als eine gibt, die mit der Regex übereinstimmt.
Natürlich
/claudio/
könnte der reguläre Ausdruck vereinfacht werden, um:Dann fehlt nur noch, dass alle anderen Zeilen unverändert gedruckt werden:
quelle