Search code examples
regexsedcygwin

Replace string if first letter is uppercase using sed


I try to write sed answer to this question Edit a file using sed/awk using:

sed -e 's/^[A-Z]/$:$&/' file.txt

but the result is:

wednesday
$:$Weekday

$:$thursday
$:$Weekday

$:$friday
$:$Weekday

$:$saturday
$:$MaybeNot

$:$sunday
$:$MaybeNot

$:$monday
$:$Weekday

$:$tuesday
$:$Weekday

Why it replace if first character is lower case?


Solution

  • This is a "feature" according to this bug report caused by unexpected character ordering in the locale, further explained here and here.

    $ locale
    LANG=en_GB.UTF-8
    LC_CTYPE="en_GB.UTF-8"
    LC_NUMERIC="en_GB.UTF-8"
    LC_TIME="en_GB.UTF-8"
    LC_COLLATE="en_GB.UTF-8"
    LC_MONETARY="en_GB.UTF-8"
    LC_MESSAGES="en_GB.UTF-8"
    LC_ALL=
    
    $ echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | sed -e 's/[A-Z]/./g'
    ..........................a.........................
    
    $ echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | sed -e 's/[a-z]/./g'
    .........................Z..........................
    
    $ echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | LC_ALL=C sed -e 's/[A-Z]/./g'
    ..........................abcdefghijklmnopqrstuvwxyz
    
    $ echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | LC_ALL=C sed -e 's/[a-z]/./g'
    ABCDEFGHIJKLMNOPQRSTUVWXYZ..........................
    
    $ echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | sed -e 's/[[:upper:]]/./g'
    ..........................abcdefghijklmnopqrstuvwxyz
    
    $ echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | sed -e 's/[[:lower:]]/./g'
    ABCDEFGHIJKLMNOPQRSTUVWXYZ..........................
    
    $ sed --version
    GNU sed version 4.2.1