Sed-Skript, um "Ich" in einer Textdatei zu verwenden

624
nickeb96

Ich versuche, einen sed-Befehl zu erstellen, der das Pronomen I in einer Textdatei großschreibt. Zum Beispiel "Ich mag Hunde." sollte "Ich mag Hunde" sein. Bisher habe ich:

sed 's/ i / I /g' 

Dies funktioniert in verschiedenen Szenarien nicht. Wie wenn es eine Interpunktion um das i gibt .

Hier ist eine Liste von Szenarien, an die ich gedacht habe, die der Befehl verarbeiten kann:

  • Es gibt mehrere " Ich " in einer Textzeile. Ich denke, das kann nur durch die gFlagge am Ende angegangen werden .
  • Das Ich hat eine Interpunktion. Zum Beispiel ein Komma oder ein Punkt danach oder ein Zitat oder eine Klammer davor oder danach.
  • Das ' i ' ist das erste oder letzte Zeichen in der Zeile. Das bedeutet, dass Sie nicht einfach nach Leerzeichen oder Interpunktionszeichen suchen können.
  • Jedes reguläre Ich in einem Wort bleibt allein. Zum Beispiel "f i ref i ghter" nicht in gedreht werden sollte "f I ref I ghter".
2

2 Antworten auf die Frage

5
user10354138

Angenommen, Sie verwenden GNU sed. Eine Möglichkeit ist

sed 's/\([[:space:]]\|[[:punct:]]\)i\([[:space:]]\|[[:punct:]]\)/\1I\2/g' 

oder sowas ähnliches. Der Fall der Zeile, die mit "Ich mag Hunde" beginnt, bleibt jedoch bestehen, da vor dem Pronomen kein Leerzeichen steht. Eine Möglichkeit, dies zu beheben, ist

sed 's/\(^\|[[:space:]]\|[[:punct:]]\)i\([[:space:]]\|[[:punct:]]\)/\1I\2/g' 

Dies hat immer noch den Fall, wenn Sie ein fortlaufendes "i" wie in "ii" haben, aber ich kann mir keinen Grund vorstellen, warum dies im englischen Text vorkommen würde, es sei denn, man schrieb irrtümlich "ii sir", wenn die richtige Phrase "aye" lautet aye sir '.

Es gibt auch Ecken und Kanten, wenn Sie auch römische Kleinbuchstaben verwenden. Das sed-Skript kann nicht sagen, ob 'ich' ein Pronomen oder die römische Zahl ist, aber es gibt wirklich keine gute Lösung für dieses.

Eine Problemumgehung für den Fall "ii" besteht darin, die Umwandlung zweimal anzuwenden. Dies kann mit einem einzigen Befehl erreicht werden: `sed -e 's ...' -e 's ...'`. Kamil Maciorowski vor 6 Jahren 0
Ich habe versucht, zwei Dinge nicht zweimal zu machen, aber ich denke, wenn dies der Fall ist, ist dies der einzige Weg. user10354138 vor 6 Jahren 0
2
G-Man

Eine einfache Lösung (mit GNU sed):

sed 's/\bi\b/I/g' 

Dies ist im Grunde das gleiche Konzept wie die andere Antwort - Ersetzen Sie "i" durch "I", wenn es nicht Teil eines größeren Wortes ist.  \bscheint nicht in der sed man-Seite erwähnt zu werden, wird aber im GNU sed-Handbuch erklärt :

\b

    Stimmt mit einer Wortgrenze überein. Das heißt, es stimmt überein, wenn das Zeichen links ein Wort ist und das Zeichen rechts ein Nicht-Wort oder umgekehrt.

      $ echo "abc %-= def." | sed 's/\b/X/g' XabcX %-= XdefX. 

Sogar das Handbuch sagt nicht explizit (aber das Beispiel zeigt), dass es \bmit dem Anfang und dem Ende der Zeile übereinstimmt. Es passt zu keinem Zeichen. Er stimmt mit der Nullzeichenfolge überein, die zwischen einem "Wort" und einem "Nicht-Wort" Zeichen (in beliebiger Reihenfolge) oder am Anfang und Ende der Zeile (wie ^und  $) angezeigt wird . Wir müssen uns also nicht darum kümmern, (mit \(\)) die Charaktere zu erfassen, denen sie entsprechen, und sie durch \1und zu ersetzen \2. Und da \bkeine Zeichen übereinstimmen, funktioniert dieser Befehl i i(ändert ihn in I I).