Wie kann ich den gesamten Text nach einem Zeichen in Bash entfernen?

147

Wie kann ich den gesamten Text nach einem Zeichen, in diesem Fall einem Doppelpunkt (":"), in Bash entfernen? Kann ich den Doppelpunkt auch entfernen? Ich habe keine Ahnung wie.

Nathan
quelle

Antworten:

134

Ein Beispiel könnte nützlich gewesen sein, aber wenn ich Sie richtig verstanden hätte, würde dies funktionieren:

echo "Hello: world" | cut -f1 -d":"

Dies wird "Hallo: Welt" in "Hallo" umwandeln.

Eldad Mor
quelle
5
cutfunktioniert, aber ich Dennis 'Antwort ist besser und flexibler. Weiß jemand, ob es einen neuen Prozess hervorbringt wie cut?
JoBu1324
3
Es ist besser, die integrierten Parametererweiterungsfunktionen von Bash zu verwenden, als Subshells zu generieren, auf denen Tools wie basenameund ausgeführt cutwerden. Siehe Dennis 'Antwort unten
Louis Maddox,
1
cutkann von stdin lesen, daher ist es besser, besonders wenn Sie eine sehr lange Zeichenfolge haben, die Sie verarbeiten müssen, wie den Inhalt einer Datei.
Sahas
1
Und wie würde es angewandt werden hello: world. Das ist eine halbe Antwort.
K - Die Toxizität in SO nimmt zu.
Es kann mit der Substitutionssyntax auch wie {var /: / ''} durchgeführt werden, funktioniert aber nur in bash ..
Mahesh
263

In Bash (und ksh, zsh, dash usw.) können Sie die Parametererweiterung verwenden, mit %der Zeichen vom Ende der Zeichenfolge oder #Zeichen vom Anfang der Zeichenfolge entfernt werden. Wenn Sie ein einzelnes dieser Zeichen verwenden, wird die kleinste übereinstimmende Zeichenfolge entfernt. Wenn Sie das Zeichen verdoppeln, wird das längste entfernt.

$ a='hello:world'
$ b=${a%:*}
$ echo "$b"
hello
$ a='hello:world:of:tomorrow'
$ echo "${a%:*}"
hello:world:of
$ echo "${a%%:*}"
hello
$ echo "${a#*:}"
world:of:tomorrow
$ echo "${a##*:}"
tomorrow
Bis auf weiteres angehalten.
quelle
6
Dies ist eine native Shell-String-Manipulation, sodass keine zusätzlichen Prozesse erzeugt werden. Referenz Bash Parameter Substitution , Bash String Manipulation und besseres Bash Scripting
Dodzi Dzakuma
@denniswilliamson Wie könnte ich gelöscht 2 Zeichen nach einer bestimmten Zeichenfolge wie hello:worldwerden wird hello:wodurch den Einsatz ${a%:*}?
3kstc
Tolle Antwort, vielen Dank, aber es wird schön sein, auch hinzuzufügen "${a##*:}", nur zu bekommen tomorrow=)
avtomaton
1
@openCivilisation: Dann müssen Sie wahrscheinlich den regulären Ausdruck verwenden : a='hello:world:of:tomorrow'; pattern=''^([^:]*:).*$'; [[$ a = ~ $ pattern]]; echo "$ {BASH_REMATCH [1]}" `. Das passt nur, wenn es einen Doppelpunkt gibt. Wenn dies optional sein soll, muss ein anderes Muster verwendet werden. Eine Erklärung von Bash-Regexen (und Regexen im Allgemeinen) würde den Rahmen dieser Kommentare sprengen. Sie können andere Fragen finden, die dies diskutieren, oder Ihre eigenen posten.
Bis auf weiteres angehalten.
1
@ kp123: Es ist das erste Beispiel in meiner Antwort. Das zweite Mal, wenn ich es zeige (wo "morgen" entfernt wird), ist es fast genau die Situation, nach der Sie fragen.
Bis auf weiteres angehalten.
9
$ echo 'hello:world:again' |sed 's/:.*//'
hello
sk8asd123
quelle
4
egrep -o '^[^:]*:'
cdhowie
quelle
Kannst du erklären, wie man das interpretiert? Danke.
rɑːdʒɑ
1
egrepist grep mit -E. Es macht hier keinen Unterschied zum regulären grep. -oweist grep an, nur den Teil der Zeile auszudrucken, der dem Ausdruck entspricht. ^verankert das Match am Anfang einer Linie. [^:]*Entspricht null oder mehr Zeichen, die nicht das :Zeichen sind. :passt zum Charakter :.
CDOWIE
Nochmals vielen
3

Angenommen, Sie haben einen Pfad mit einer Datei in diesem Format:

/dirA/dirB/dirC/filename.file

Jetzt möchten Sie nur den Pfad, der vier "/" enthält. Art

$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-4 -d"/"

und Ihre Ausgabe wird sein

/dirA/dirB/dirC

Der Vorteil der Verwendung von cut besteht darin, dass Sie sowohl das oberste Verzeichnis als auch die Datei (in diesem Beispiel) ausschneiden können, wenn Sie also eingeben

$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-3 -d"/"

Ihre Ausgabe wäre

/dirA/dirB

Obwohl Sie dasselbe von der anderen Seite der Zeichenfolge aus tun können, wäre dies in diesem Fall nicht so sinnvoll wie das Tippen

$ echo "/dirA/dirB/dirC/filename.file" | cut -f2-4 -d"/"

führt zu

dirA/dirB/dirC

In einigen anderen Fällen kann auch der letzte Fall hilfreich sein. Beachten Sie, dass am Anfang der letzten Ausgabe kein "/" steht.

Nico Feulner
quelle
2
Was ist, wenn Sie ein Verzeichnis "/resources/views/admin/users/relationships/posts.blade.php" haben und nach dem LETZTEN Auftreten des "/" alles abschneiden möchten, da Sie NICHT wissen, wie viele "/ "Zeichen sind in der Zeichenfolge. Hier möchte ich also, dass die Ausgabe "/ resources / views / admin / users / Relationships /" lautet (oder sogar / resources / views / admin / users / Relationships ohne den abschließenden Schrägstrich). Wie würdest du das machen?
kp123
-1

Schneiden Sie alles nach der letzten Instanz von ":" ab.

cat fileListingPathsAndFiles.txt | grep -o '^.*:'

und wenn Sie das letzte ":" fallen lassen wollten

cat file.txt | grep -o '^.*:' | sed 's/:$//'

@ kp123: Sie möchten ersetzen :durch /(wo der sed Doppelpunkt sein sollte \/)

S Hunter Simpson
quelle