
Ich suche nach einer Möglichkeit, mit einer durch Pipes getrennten Datei in UNIX für JEDE ZEILE Folgendes zu tun, und bin nicht sicher, wo ich anfangen soll:
- Suchen Sie in einer Textzeile nach einem Zeichen (vermutlich mithilfe von GREP?)
- Wenn gefunden, fügen Sie am Ende dieser Zeile Text hinzu (mit SED?)
- Wenn nicht gefunden, suchen Sie nach einem anderen Zeichen in der gleichen Zeile
- Wenn gefunden, fügen Sie am Ende der Zeile Text hinzu, andernfalls tun Sie nichts
- SCHLEIFE FÜR ALLE ZEILEN IN DER DATEI
Ich bin für alle Hinweise dankbar.
Antwort1
Das ist alles sed
Arbeit, Sie brauchen kein zusätzliches Werkzeug:
Angenommen, Sie möchten foo
am Ende einer Zeile, die ein enthält, f
und bar
am Ende einer Zeile ohne f
, aber mit einem hinzufügenb
sed '/f/{
s/$/foo/
b
}
/b/s/$/bar/'
Sie können Zeilen mit "adressieren" /pattern/
, sodass die folgenden Befehle nur ausgeführt werden, wenn sie das Muster enthalten. Im Beispiel lösen also nur Zeilen, die ein enthalten, f
die Ausführung des s
Ersetzungsbefehls aus, und b
(die {}
gruppieren die Befehle, sodass alles darin nur angewendet wird, wenn die Adresse übereinstimmt. Die b
verzweigt zum Ende des Skripts, um das Anhängen einer weiteren Zeichenfolge für einen übereinstimmenden zu vermeiden b
.
Anderer Ansatz ohne Verzweigung:
sed '/f/s/$/foo/;s/^[^f]*b[^f]*$/&bar/'
sed
Als Übung können Sie dies mit etwas Wissen selbst herausfinden und man sed
es ggf. anwenden.
Antwort2
Wenn Sie für beide Szenarien die gleiche Textzeichenfolge am Ende der Zeile hinzufügen möchten (zu suchende Zeichen: „X“ oder „Y“), können Sie dies wie folgt tun:
sed -e 's/[XY].*/&__ADDEDTEXT__/' yourfile
Wenn Sie hingegen je nach Zeichen separate Texte am Ende der Zeilen platzieren möchten, können Sie Folgendes tun:
sed -e '
/X/s/$/__TEXT1__/; t
/Y/s/$/__TEXT2__/
' yourfile
Hier verwenden wir den t
Befehl (read as test), um festzustellen, ob der vorherige s///
Befehl erfolgreich war, und springen zum Ende des Sed-Codes in der aktuellen Zeile. Beachten Sie auch die Syntax: /regex/s/// => wenn eine Zeile den regulären Ausdruck enthält, führen Sie die Ersetzung in der Zeile durch.
Antwort3
Perl ist auch ein nützliches Tool, mit dem sich alles problemlos in einem Durchgang erledigen lässt.
Am Beispiel von @Philippos würde ein Perl-Programm also folgendermaßen aussehen (ein Teil der Syntax ist optional und wurde zur Verdeutlichung hinzugefügt):
perl -pe '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
Dies liest file
das Ergebnis und gibt es aus. Sie können die Datei auch direkt „bearbeiten“, indem Sie -pi -e
anstelle von verwenden -pe
( -i
bedeutet „direkt“), also:
perl -pi -e '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
Es gibt wahrscheinlich auch eine Möglichkeit, dies awk
mit Ruby zu tun (das sieht fast gleich aus, pingen Sie mich an, wenn Sie Beispiele möchten), obwohl erste Tests bei mir fehlgeschlagen sind (ich bin nicht so gut in AWK), und es kann auch mit reinem Bash Spaß machen.