Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing some uppercase character with lowercase character using sed

Tags:

bash

sed

awk

I have a file named file.txt that contains absolute paths. It looks like that:

J:/Folder/inner
J:/Folder/inner2

First, I wanted to write a bash script that replaces the J:/ with /cygdrive/j/. So I did it like this:

sed -i 's/J:\//\/cygdrive\/j\//g' file.txt                    

and it works as expected.
But now I want something more complicated: the absolute paths don't have to start with J- they can start with C, D, E ...
I want to do the same thing as I did above, just that I don't know what will be the first letter. For example: C:/Folder/inner will become /cygdrive/c/Folder/inner and D:/Folder/inner will become /cygdrive/d/Folder/inner.
I understand that I need to use regular expression for acheiving that, but I have not found the way to do this. Do you know how can I get what I want?

like image 600
Mark Avatar asked Jan 29 '23 15:01

Mark


1 Answers

To do it with sed, you'd need support for changing case which GNU sed provides. So, this would not be a portable solution

$ cat file.txt 
J:/Folder/inner
J:/Folder/inner2
C:/Folder/inner
D:/Folder/inner

$ sed -E 's#^(.):#/cygdrive/\l\1#' file.txt 
/cygdrive/j/Folder/inner
/cygdrive/j/Folder/inner2
/cygdrive/c/Folder/inner
/cygdrive/d/Folder/inner
  • -E to enable ERE, in this case avoids having to escape the ()
    • some versions might support -r only instead of -E
  • ^(.): match a character and : from beginning of line
    • use ^([A-Z]): or ^([A-Za-z]): as needed to match only alphabets
  • /cygdrive/\l\1 in replacement section, the string /cygdrive/ and lowercase version of captured character will be used
  • Note the use of # as delimiter character, helps to avoid escaping /s in search/replacement sections
    • any character other than \ and newline character can be used
  • add -i once the solution is working as expected
like image 127
Sundeep Avatar answered Feb 05 '23 15:02

Sundeep