1

I am trying to master VI and found some nice tricks to replace a letter with a single :%s/ command and this works. If I'd like to replace for example word with wardos I can use :%s/word/wardos/g and then hit enter.

But how do I replace those accented characters like é, á, Á etc?

1
  • After writing my answer I'm realizing that you didn't mentioned by what you want to replace the accented characters. You just want to remove the accents or you simply want to match them and replace them with anything else?
    – statox
    Oct 17, 2018 at 8:15

3 Answers 3

5

If you want to match just a single character that has an accent, you can simply include it in a search:

:%s/café/restaurant/g

You can type the accented character either using your operating system's input features, or with Vim's digraphs feature (see :help c_CTRL-k)

If you want to ignore the accents, you can use an equivalence class (See :help /[[=).

e.g. Replace both cafe and café with restaurant:

:%s/caf[[=e=]]/restaurant/g

Replace all e-like characters with ASCII e characters:

:%s/[[=e=]]/e/g
1
  • Thank you :%s/[[=e=]]/e/g works excellent.
    – Jason335
    Oct 17, 2018 at 11:31
5

The accents are part of the word's spelling. You're asking us how to use vi to take a document with correctly-spelled words and introduce spelling errors.

The days where you could get away with ignoring Unicode are long past.

There are languages without a J, such as classical Latin. Would you not be annoyed if people called you "Iason335" on this site?

Of the vi clones, Vim has by far the best Unicode support. Vim likes UTF-8 best, though on Windows UTF-16 is sometimes a better idea. See the unicode section of the Vim manual for more information.

If you absolutely must crush Unicode back to a legacy encoding such as the ancient 7-bit ASCII standard, there are several options I'd choose before resorting to a blind vi substitution command:

  1. Replace the words on a case-by-case basis using human intelligence, since accented letters don't have the same meaning in all human languages, so there is no dumb repetitive rule you can run that works in all cases:

    • The Germanic name Jörg is best spelled Joerg in ASCII, not "Jorg".

      But please beware: the "ö" → "oe" rule only applies to German. It doesn't apply even to closely-related languages like Dutch, though the same process exists with different orthography.

    • English is largely German-derived, but in properly-spelled English, the two-dot accent on top of a letter is almost always a diaeresis, not an umlaut

      For instance, the English word "cooperate" is sometimes spelled "coöperate" to indicate that the first syllable is "co," not "coop," as in "chicken coop." The proper ASCII-ization is therefore not "cooeperate".²

      For another example, the English surname Brontë uses a diaeresis to indicate that the "e" isn't silent, as an English speaker may well expect, causing it to be pronounced as if it were spelled "Bront". The diaeresis tells us that the final "e" is a separate syllable, so the name must be properly pronounced "BRONT-ay". The proper ASCII-ization is "Bronte", not "Brontee" or something else.³

    • In the Swedish alphabet, "ä" and "ö" are considered separate letters in their own right rather than accented versions of other letters; there is no umlaut as such in Swedish. The ASCII transliteration rule for German is simply incorrect for Swedish. For example, the Swedish name Ångström is best ASCII-ized as "Angstrom" not "Angstroem".

  2. Use iconv(1) to convert the file automatically.

    This is likely to do less damage to your file than a blind vi substitution because the conversion routines were written by experts in the topic, who have thought through issues like the above and more.

    If your target is plain ASCII, you will have to use the //translit modifier, the //ignore modifier, or the -c flag to make this work. I recommend trying them in that order. For example, on the input text "Please coöperate with Jörg.", iconv -f utf-8 -t ascii//translit gives

    Please coo"perate with Jo"rg.
    

    as output. It is doing its best to show that the input text once had dots over the letters.

    A better plan would be to use an 8-bit extension to ASCII that also works on your system, such as ISO 8859-1, which can encode the examples I've given so far directly: iconv -f utf-8 -t iso-8851-1.

    You can use iconv from within vi using the various pipe commands. For example, to read a UTF-8-encoded file x as ASCII into the current buffer:

    :r !iconv -t ascii//translit x
    

    Or, you could open a file as Unicode, then mark a section of it using normal vi commands (e.g. Vim's V block selection command) then convert it in place using iconv:

    :'<,'>!iconv -t ascii//translit
    

    You don't have to type the first part if starting from a Vim block selection: the first character you type is the !, and the rest is filled in automatically. You do have to type it all if using other types of vi marks.

  3. Use the Perl module Text::Unidecode instead of iconv. Because it isn't part of the Perl core, you'll have to install it by hand.

    Beware that it merely provides a different sort of "wrong" than iconv //translit. Its documentation is well worth reading, particularly the section "When You Don't Like What Unidecode Does".

    You can use that from within Vim using this mapping in your ~/.vimrc file:

    map <F6> !}perl -C -MText::Unidecode -ne 'print unidecode( $_)'<CR>
    

    Pressing F6 will convert the current paragraph.


Asides:

  1. Excepting loanwords, of course.

  2. Some people spell the word "co-operate" to side-step this problem.

  3. There is no "ë" in German, so an "ö" → "oe" type of rule could not properly come into effect here anyway.

2

You can chain the substitutions with the pipe |

For example :

:%s/é/e/e | %s/à/a/e | %s/....

This way, you could replace several accentuated chars in one line

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.