Script Sed per capitalizzare "I" in un file di testo


2

Sto cercando di creare un comando sed che capitalizza il pronome I in un file di testo. Ad esempio "mi piacciono i cani". dovrebbe essere "Mi piacciono i cani". Finora ho:

sed 's/ i / I /g'

Questo non funziona in diversi scenari. Come se ci fosse la punteggiatura attorno all'i .

Ecco un elenco di scenari a cui ho pensato che il comando dovrebbe essere in grado di gestire:

  • Esistono più " i " su una riga di testo. Penso che questo possa essere risolto solo avendo la gbandiera alla fine.
  • L'' i 'ha punteggiatura attorno ad esso. Ad esempio una virgola o un punto dopo di essa, oppure una citazione o una parentesi prima o dopo di essa.
  • La ' i ' è il primo o l'ultimo carattere della linea. Ciò significa che non puoi semplicemente controllare spazi bianchi o punteggiatura intorno.
  • Qualsiasi " io " in una parola viene lasciato solo. Per esempio "f i ref i ghter" non dovrebbe essere trasformata in "f I ref I ghter".

Risposte:


5

Supponendo che tu stia usando GNU sed, un modo è

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

o qualcosa di simile. Questo lascia ancora il caso della linea che inizia con "mi piacciono i cani" perché non c'è spazio prima del pronome. Un modo per risolvere questo è

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

Questo lascia ancora il caso quando hai 'i' consecutivo come in "ii", ma non riesco a pensare a nessun motivo per cui questo dovrebbe accadere nel testo inglese, tranne quando uno ha erroneamente scritto 'ii signore' quando la frase corretta è 'aye si signore'.

Ci sono anche bordi irregolari se si usano anche numeri romani minuscoli. La sceneggiatura di sed non sarà in grado di dire se 'i' è un pronome o un numero romano, ma in realtà non esiste una buona soluzione a quello.


Una soluzione alternativa al i icaso consiste nell'applicare la trasformazione due volte. Ciò può essere ottenuto da un comando: sed -e 's…' -e 's…'.
Kamil Maciorowski il

Stavo cercando di evitare di fare le cose due volte, ma suppongo che se la spinta arriva a spingere questo è l'unico modo.
user10354138,

2

Una soluzione semplice (con GNU sed):

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

Questo è fondamentalmente lo stesso concetto dell'altra risposta: sostituire "i" con "I" quando non fa parte di una parola più grande.  \bsembra non essere menzionato nella pagina man di sed, ma è spiegato nel manuale GNU sed :

\b

    Corrisponde a un limite di parole; cioè corrisponde se il personaggio a sinistra è un carattere "parola" e il carattere a destra è un carattere "non parola", o viceversa.

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

Anche il manuale non dice esplicitamente (ma mostra l'esempio) che \bcorrisponde all'inizio e alla fine della riga. Non corrisponde a nessun personaggio; corrisponde alla stringa nulla che appare tra un carattere di "parola" e un carattere di "non parola" (in entrambi gli ordini), oppure all'inizio e alla fine della riga (come ^$). Quindi non dobbiamo preoccuparci di catturare (con \(... \)) i personaggi che corrispondono e sostituirli con \1e \2. E, poiché \bnon corrisponde a nessun personaggio, questo comando funziona i i(cambiandolo in I I).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.