0

I have hundreds of bash scripts that have upper case variables like so

#!/bin/bash

FOO=bar
RED=blue
UP=down

I am making them lower case like so

for var in FOO RED UP
do
    grep -rl '\<$var\>' | xargs sed -i 's/\<$var\>/$(echo "$var" | tr '[:upper:]' '[:lower:]')/g"
done

Now I have encountered files with hundreds of variable declerations and it is becoming too difficult to copy paste each one. I tried automating the process like so

grep -rl '\w*=[^=]' | xargs sed -E "s/(\w*)=([^=])/$(echo \1 | tr '[:upper:]' '[:lower:]')=\2/g"

But the problem lies in $(echo \1...) which obviously will fail

Is there a way to quickly find all vars and convert to lowercase using regex?

EDIT:

As requested, assume we have 1 file like so

#!/bin/bash

AAA="hello world"
AAB="hello world"
...
ZZZ="hello world"

And assume I have a large number (>10000) nested (in directories or sub-directories) like so

#!/bin/bash

echo $AAA
echo $AAB
...
echo $ZZZ
if [ $AAA == "foo" ]
then
    #do something
fi

I want to search for any assignments (\w*=[!=]) and then do a word replace on that variable to make it lower case. Note the if condition, I through that in there to show that there may be a case of a word followed by 2 equations, but we are matching for only 1 equation (and no space)

Edit 2: Note that I want only the variable names to be converted to lower case, not everything

# Current Input
SOME_VAR="Humpty Dumpty had a great FALL"

# Desired Output
some_var="Humpty Dumpty had a great FALL"
  • Are you using GNU sed? Try `echo A | sed 's/./\L&/'` and see what happens. – Beta Jun 20 '21 at 17:44
  • 2
    Please [edit] your question to, in your sample input, include examples of where the variables are used as well as where they're declared as well as where they're defined and add the expected output given that input. How will you handle builtin variables like `HOME` or text in strings like `echo "ERROR: the sky fell"` or existing Camel-case text like `printLog() { do_stuff; }`? – Ed Morton Jun 20 '21 at 17:49
  • @EdMorton, see edits – francistheturd Jun 20 '21 at 18:05
  • Does this answer your question? [sed one-liner to convert all uppercase to lowercase?](https://stackoverflow.com/questions/4569825/sed-one-liner-to-convert-all-uppercase-to-lowercase) – dahiya_boy Jun 20 '21 at 18:06
  • @Francis - thanks but you didn't show how you want builtin variables like HOME and PWD or camel-Case symbols like `printLog` handled. Or by `assume we have 1 file like so` are you saying you need a script to read 1 specific such file first and then search the rest of your files for the ONLY the symbols defined in that file first file, not any additional symbols we find as `FOO=7` in any of the other files? Or something else? – Ed Morton Jun 20 '21 at 20:33
  • If you create sample input/output [mcve] as I suggested and clarify your requirements then we can help you. It's always trivial to find the strings you want but much harder to not find similar strings you don't want so without having your sample input/output include some of those strings you don't want changed it's really not very useful for testing with. – Ed Morton Jun 20 '21 at 20:41
  • 1
    Also in your example include upper case strings in comments, some of which are symbols that should be changed and some that aren't, along with arrays, e.g. `echo "${FOO[@]}"` and arithmetic e.g. `$(( FOO + 7 ))` and substitution `$(FOO#%.txt}` and any other use-cases that you can think of that aren't included in your example so far. – Ed Morton Jun 20 '21 at 20:53
  • You are right about `$(foo)` and `$((foo))` – francistheturd Jun 20 '21 at 21:57
  • @francistheturd : How do you handle those environment variables, where the consumer of the varialbe (typically a program, which you invoke), expects them in upper case? Example: `PERL5LIB` or `LD_LIBRARY_PATH`)? And how are you going to distinguish the **variable** `FOO` (which you want to turn into `foo`) from a program `FOO` or a program argument `FOO`? Honestly, this really invites errors to appear, and all this just for aesthetic pleasure. I would simply leave them in upper case, if the original programmer wanted them in this way. – user1934428 Jun 21 '21 at 09:51

1 Answers1

0

The only solution that worked for me was to go through and replace the variable names to lower case in three steps

 # Change all SOME_VAR=... to some_var=...                                 
 grep -rl '\w\+=' | xargs sed -i 's/\w\+=/\L&/g'                             
                                                                             
 # Change all $SOME_VAR to $some_var                                         
 grep -rl '$\w\+' | xargs sed -i 's/$\w\+/\L&/g'                             
                                                                             
 # Change all ${SOME_VAR} to ${some_var}                                     
 grep -rl '$\w\+' | xargs sed -i 's/${\w\+}/\L&/g'

Then I went back and changed the few environment variables back to upper case

  • 2
    That would change text that appears in strings, builtin variable names, etc. and obviously it'd be far better to not change environment variables than change them and then have to go around again and change them back. It also won't find arrays, e.g. `echo "${FOO[@]}"` or arithmetic e.g. `$(( FOO + 7 ))` or substitution `$(FOO#%.txt}` and probably other things that you should include in your sample input/output to test with. – Ed Morton Jun 20 '21 at 20:44