2

I have a txt file like this

John Doe;john Doe is ...;he lives in ...
Mike Nelson;mike Nelson works for ...;he makes ...
Marcy William;marcy's mother is ...;marcy travels a lot... 

I want to convert every character following a semicolon to uppercase, so the final result is

John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...

keeping the rest intact.

This file contains accented letters and is coded in UTF-8.

How do I do that using sed, awk or whatever using terminal?

Thanks

  • perl -pe 's/;(.)/;\u$1/g'. – user414777 Sep 19 at 14:48
  • almost there. This is not working with accented letters. – Duck Sep 19 at 14:50
  • 2
    It does, if you're telling perl to use utf-8: echo ';ük;ук' | perl -CiIO -pe 's/;(.)/;\u$1/g' => ;Ük;Ук – user414777 Sep 19 at 14:52
  • brilliant. This second command is working perfectly. Please make this an answer. – Duck Sep 19 at 14:56
9

GNU Sed:

sed 's/;./\U&/g' file

For every character following a semicolon (;.), we make it uppercase with the \U special sequence. The g flag substitutes all occurrences in a line.

If GNU Sed is not available, a POSIX compliant alternative is to use Ex.

printf '%s\n' '%s/;./\U&/g' '%p' | ex file

The substitute command is the same, but all lines should be addressed with %. %p prints the output. If you wish to directly modify the file, replace %p by x.

| improve this answer | |
5

Here's one way, using perl:

perl -C -pe 's/;(.)/";" . uc($1)/eg' file

Since you don't show any accents in your input file, I used this for testing:

$ cat file
John Doe;john Doe is ...;he lives in ...
Mike Nelson;mike Nelson works for ...;he makes ...
Émilie du Châtelet;émilie du Châtelet;works for ...;she makes ...
Marcy William;marcy's mother is ...;marcy travels a lot...
Άσπα Κυριάκου;άσπα's brother is ...; άσπα likes fish

Which produces:

$ perl -C -pe 's/;(.)/";" . uc($1)/eg' file
John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Émilie du Châtelet;Émilie du Châtelet;Works for ...;She makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...
Άσπα Κυριάκου;Άσπα's brother is ...; άσπα likes fish

Explanation

  • -C: (see man perlrun for details) essentialy, this enables utf8.
  • -pe: read the input file line by line and print every line after applying the script given by e.

The work happens in the substitution operator, whose general format is s/old/new/flags. This means it will subsitute old with new and flags control how it will work. Here, the flags used are e which enables perl code in the substitution and g which means "apply to all matches of the line".

The ;(.) captures every character found after a ; and saves it as $1. We then replace this with a ;, and the character converted to upper case (uc($1)).

| improve this answer | |
3

using Raku (formerly known as Perl6)

An advantage of the Perl6/Raku project is that it's designed to handle Unicode gracefully, from the ground up. Thanks to @terdon for posting a nice test file:

~$ raku -pe 's:g/ \;(.) /;{$0.uc}/;'  terdon_uni.txt
John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Émilie du Châtelet;Émilie du Châtelet;Works for ...;She makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...
Άσπα Κυριάκου;Άσπα's brother is ...; άσπα likes fish

Above we see the capture of the first character after a semicolon. The :g flag (short for :global) moves to the head of the s/// operator, so we know from the get-go what sort of match we're after. Note captures in Raku start $0, $1, $2, etc. The 'matching' (left) half of the s/// operator is whitespace-tolerant, which improves readability. The 'replacement' (right) half of the s/// operator uses {…} to indicate a closure.

Below I use Raku's <(…)> capturing marker. Raku's <(…)> circumfix is equivalent to Perl5's \K flag. A match is performed but the <(…)> marker tells Raku to drop everything outside <(…)> and load the inside (capture) into $/. Because Raku performs the entire match but only captures the exact character(s) you want to change, writing the replacement is greatly simplified:

~$ raku -pe 's:g/ \; <(.)> /{$/.uc}/;'  terdon_uni.txt
John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Émilie du Châtelet;Émilie du Châtelet;Works for ...;She makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...
Άσπα Κυριάκου;Άσπα's brother is ...; άσπα likes fish

HTH.

https://raku.org

| improve this answer | |
2

Using @terdon's sample file and GNU sed:

$ sed -e 's/;\(.\)/;\U\1/g' file
John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Émilie du Châtelet;Émilie du Châtelet;Works for ...;She makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot...
Άσπα Κυριάκου;Άσπα's brother is ...; άσπα likes fish
$ 
| improve this answer | |
1

command

awk -F ";" '{for(i=1;i<=NF;i++){print toupper(substr($i,1,1)) substr($i,2)}}' filename|sed -e "N;s/\n/;/g" -e "N;s/\n/;/g"

output

John Doe;John Doe is ...;He lives in ...
Mike Nelson;Mike Nelson works for ...;He makes ...
Marcy William;Marcy's mother is ...;Marcy travels a lot... 
| improve this answer | |

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.