Technext
Technext

Reputation: 8117

Convert first letter to lowercase using sed

I am running a Docker Alpine based image which has bash installed.

bash --version
GNU bash, version 4.3.48(1)-release (x86_64-alpine-linux-musl)

In the following command, i am trying to convert first letter of month to lowercase but it's not working:

find ../ -type f -name "*.md" \
        -exec bash -c '
            f=${1#./}
            gzip -9 "$f"
            mv "$f".gz "$f"
            aws s3 cp "$f" s3://bucket_name/ --metadata time=$(date +%d-%b-%Y.%H%M | sed '\''s#\([A-Z]\)#\L\1#'\'') ' _ {} \;

The date attribute it assigns to the file(s) is:

"Metadata": {
    "timestamp": "10-LSep-2018.1054"
}

\L is not working in this case. The expected date should have been "10-sep-2018.1054"

How can i get it working with the bash version present in Docker image?

Upvotes: 3

Views: 1128

Answers (5)

Sam
Sam

Reputation: 859

As it turns out OP only has access to a minimal version of sed that does not recognize the \L replacement command and for his use case de-capitalizing ALL letters in the output is acceptable.

The most straightforward way to achieve this is with the command

tr [:upper:] [:lower:]

Upvotes: 3

potong
potong

Reputation: 58578

This might work for you (GNU sed):

sed 's/$/:JjFfMmAaSsOoNnDd/;s/\([JFMASOND]\)\(.*\):.*\1\(.\).*/\3\2/' file

This replaces an upper-case letter J,F,M,A,S,O,N or D with its lower-case complement.

Upvotes: 1

binary-sequence
binary-sequence

Reputation: 31

The question could have been simplified by only showing the affected part:

date +%d-%b-%Y.%H%M | sed '\''s#\([A-Z]\)#L\1#'\''

In first place let me "clean" it:

date +%d-%b-%Y.%H%M | sed 's#\([A-Z]\)#L\1#'

What I see here is that you are using L as a literal letter, not as the command. You need to escape it (\L) like this:

date +%d-%b-%Y.%H%M | sed 's#\([A-Z]\)#\L\1#'

You can test it executing:

:~# docker container run --rm alpine /bin/sh
/ # date +%d-%b-%Y.%H%M | sed 's#\([A-Z]\)#\L\1#'
10-LSep-2018.1510

Upvotes: 1

PesaThe
PesaThe

Reputation: 7509

This GNU sed should do:

$ date +'%d-%b-%Y.%H%M' | sed 's/-./\L&/'
10-sep-2018.1332

To escape it properly in bash -c '...':

bash -c '... time="$(date +"%d-%b-%Y.%H%M" | sed "s/-./\L&/")" ...'

If you don't have GNU sed available (it is needed for the \L extension), just save the date to a variable and use parameter expansion:

$ d=$(date +'%d-%b-%Y.%H%M')
$ echo "${d,,}"
10-sep-2018.1337

Upvotes: 1

Andrea Giammarchi
Andrea Giammarchi

Reputation: 3198

There are few variants of a possible answer in this other thread, but the one that seems to satisfy your needs, and it's also the easiest to read, is the following one:

sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'

That should work pretty much everywhere, including macOS.

Upvotes: 0

Related Questions