0

I've written the following bash script that utilizes awk, the aim is to set the first character to lower case. The script works mostly fine, however I'm adding an extra space when I concat the two values. Any ideas how to remove this errant space?

Script:

#!/bin/bash

foo="MyCamelCaseValue" 
awk '{s=tolower(substr($1,1,1))}{g=substr($1,2,length($1))}{print s,g}' <<<$foo

Output:

m yCamelCaseValue

edit:

Please see discussion from Bobdylan and RavinderSingh13 on accepted answer as it highlights issues with default MacOs bash version.

bash --version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19) Copyright (C) 2007 Free Software Foundation, Inc.

15
  • 1
    Use {print s""g} Commented Sep 18, 2020 at 9:05
  • 2
    @RavinderSingh13 - I was typing before the post got deleted. Anyway - yes I agree. But I was more on the principal that yes it's technically a solution - but it's not the most elegant way. His attempt was an attempt - but doesn't mean it can't be re-written and improved upon wholesale. :) Commented Sep 18, 2020 at 9:30
  • 2
    Using a 13+ year old version is kinda the problem there to be fair..... But I agreed the version might be an issue (dunno when it was introduced exactly) Commented Sep 18, 2020 at 9:35
  • 1
    Sure go for it - I've submitted a response as an alternative and we're in agreement anyway. If on a 15 year old version (i.e. macos default) and you can't upgrade then by all means do the awk etc. If not then use a proper version of bash (which you should be doing) and do it this way. Leaving this post now as I've already spent too long on it ;) Commented Sep 18, 2020 at 9:37
  • 1
    I'd happily upgrade, problem is i'm creating this script to be used by other mac users in my company. The solution is to just package so they dont have to worry about versions but I'd rather it worked with the default settings their setups have. Sounds dumb, sorry folks! I appreciate all your help :) Commented Sep 18, 2020 at 9:39

1 Answer 1

6

You were close and good try, you need not get length of line here, substr is intelligent enough to get the rest of the length of you mention a character position and don't give till where it should print(length value). Could you please try following.

(Usually these kind of problems could be solved by bash itself but when OP tried bash solution provided by @bob dylan its having issues because of OLD version of BASH, hence I am undeleting this one which is working for OP)

echo "$foo" | awk '{print tolower(substr($0,1,1)) substr($0,2)}' Input_file

Explanation:

  • Use substr function of awk to get sub-strings in current line.
  • Then grab the very first letter by substr($0,1,1) and wrap it inside tolower to make it in small case.
  • Now print rest of the line(since first character is already being captures by previous substr) by doing `substr($0,2) this will print from 2nd character to last of line.


EDIT by @bob dylan:

https://www.shell-tips.com/mac/upgrade-bash/

MacOS comes with an older version of bash. However if you're on 4+ you should be able to use the native bash function to translate the first character from upper to lower:

$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ cat foo.sh
#!/bin/bash
foo="MyCamelCaseValue"
echo "${foo,}"
$ bash foo.sh
myCamelCaseValue

Further examples for the whole string, to lower, to upper etc.

$ echo $foo
myCamelCaseValue
echo "${foo,}"
myCamelCaseValue
$ echo "${foo,,}"
mycamelcasevalue
$ echo "${foo^}"
MyCamelCaseValue
$ echo "${foo^^}"
MYCAMELCASEVALUE
Sign up to request clarification or add additional context in comments.

8 Comments

Worked perfectly :) I'll accept the answer when able to
Because you're basically trying to pipe from input and do some funkiness with regards to length. Doing just "${foo,}" = the same as saying "tr the first character from upper to lower) without needing an awk and length check, garbling etc.
And mine does. You're on about file wide etc, but his example gives a specific value to $foo and you make an assumption - my point is ops solution might work - but it's overkill for a native function in bash
Is it beneficial if I edit the original question and mention the older version of Bash and the Mac setup? edit: I see the answer reflects this info, i'll leave the question unedited
All sorted :) got there in the end!
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.