Versuch, mit sed regex ein am Ende eines Wortes stehendes Zeichen zu löschen

Versuch, mit sed regex ein am Ende eines Wortes stehendes Zeichen zu löschen

Ich habe keine Erfahrung mit Regex und sed und versuche, einen meiner Meinung nach unkomplizierten Regex zu erstellen: Ich möchte den Buchstaben am Ende des Wortes entfernen, wenn es ein „o“ ist.

  • Eingabezeichenfolge: Hallo, Hallo
  • Erwartete Ausgabe: Hell Hell

Die gute Nachricht: Ich kann das „o“ entfernen, wenn es am Ende der Zeichenfolge steht:

$ echo 'Hello Hello' |sed 's/\(.*\)o/\1/g'
Hello Hell
$ echo 'Hello Hello' |sed 's/\(.*\)o$/\1/g'
Hello Hell

Die schlechte Nachricht: Ich kann es nicht aus Wörtern entfernen, die weiter vorne in der Zeichenfolge stehen. Ich habe das mit allen Ankersymbolen versucht, die mir einfallen. Das Ergebnis ist, dass keines der wortfinalen 'o's entfernt wird:

$ echo 'Hello Hello' |sed 's/\(.*\)o\b/\1/g'
Hello Hello
$ echo 'Hello Hello' |sed 's/\(.*\)o\>/\1/g'
Hello Hello
$ echo 'Hello Hello' |sed 's/\(.*\)o\W/\1/g'
Hello Hello
$ echo 'Hello Hello' |sed 's/\(.*\)o\s/\1/g'
Hello Hello

Können Sie mir bitte helfen, meinen Verstand wiederzuerlangen, indem Sie mir sagen, was ich falsch mache?

Update: Ich habe den deutlichen Eindruck, dass mein Rechner andere Ergebnisse liefert als andere Leute. Ich verwende das Terminalfenster auf meinem Macbook. Wenn jemand etwas Licht ins Dunkel bringen kann, sagen Sie es mir bitte.

Antwort1

echo 'Hello Hello' | sed 's/o$//'

scheint mir nützlicher als Ihre

echo 'Hello Hello' | sed 's/\(.*\)o$/\1/g'

In Ihrer Frage steht, dass die Ausgabe von

echo 'Hello Hello' | sed 's/\(.*\)o\b/\1/g'

war Hello Hello, aber für mich ist es so Hello Hell. Sie können das korrigieren zu

echo 'Hello Hello' | sed 's/\([^o]*\)o\b/\1/g'

Aber

echo 'Hello Hello' | sed 's/o\b//g'

scheint mir besser.

Antwort2

Das Entfernen von „ oam Ende von Wörtern“ entspricht dem Entfernen von „ao“ zwischen einem Wortzeichen und einem Nicht-Wortzeichen (oder dem EOL). Also:

sed -r 's/(\w)o(\W|$)/\1\2/g'

Antwort3

Ich frage mich, ob „irgendwie“ spacenicht Ihr Worttrennzeichen ist. Versuchen Sie es mit etwas wie dem Folgenden:

$ echo hello hello | sed -e 's/o / /g;s/o$//'
hell hell

.Das Problem bei diesem Beispiel ist, dass Sie dasselbe auch für und ,und alle anderen Worttrennzeichen tun müssen . Match ogefolgt von einem anderen bestimmten Zeichen mit []like o[ \.,]. Aus irgendeinem Grund funktioniert das nicht für EOL $, also fügen Sie eine weitere Suchzeichenfolge mit hinzu ;. Beispiel:

$ echo hello hello, hello. toot hello | sed -e 's/o\([ \.,]\)/\1/g;s/o$//'
hell hell, hell. toot hell
$ echo $SHELL
/bin/bash
$ sed --version
sed (GNU sed) 4.4
$ set | grep IFS
IFS=$' \t\n'

Antwort4

Ich habe dies mit allen Ankersymbolen versucht, die mir eingefallen sind.

Es liegt nicht an den Ankern, sondern an der Tatsache, dass Sie eine gierige Übereinstimmung mit dem Asterisk haben. Der \(.*\)oAusdruck stimmt übereineine möglichst lange Zeichenfolge, also wird es alles auffressen bis zumzuletzt o. Es könnte oauch mit früheren übereinstimmen.

Es ist jedoch sinnlos, etwas zu erfassen und dann zurückzugeben. Sie könnten das \(.*\)und das einfach \1vollständig entfernen.

Diese würden also (zumindest in GNU sed) die o's am Ende von Wörtern entfernen:

sed 's/o\>//g' 
sed 's/o\b//g' 

Dies natürlich nur am Ende des Strings:

sed 's/o$//g' 

Und dies entfernt ein o, zusammen mit einem folgenden Nicht-Wort-Zeichen (z. B. das Leerzeichen nach Hello):

sed 's/o\W//g' 

Wenn Ihr / oder sednicht unterstützt , müssen Sie etwas anderes tun. Dies würde eine Übereinstimmung gefolgt von einem nicht-alphanumerischen Zeichen oder dem Zeilenende ergeben:\<\>\bo

$ echo "jello, jello" | sed -E -e 's/o([^[:alnum:]]|$)/\1/g'
jell, jell

Dies funktioniert beispielsweise in der sedmit OS X/macOS mitgelieferten Version.


Perl-Regexe unterstützen das Hinzufügen eines Fragezeichens an *oder +, um sie nicht-gierig zu machen. Dann würden sie mit demkürzesteMögliche Zeichenfolge:

echo "jello, jello" | perl -pe 's/(.*?)o/$1/g'
jell, jell

verwandte Informationen