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.

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.


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

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.


4
egrep -o '^[^:]*:'

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


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.


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 \/)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.