I have the following string: abcd=efgh
and I would like to uppercase all characters before the =
to get ABCD=efgh
.
After reading a bunch of posts, I tried the following:
echo "abcd=efgh" | sed -r 's/^(.*)=/\U\1\E=/'
But this returns:
UabcdE=efgh
So with the command, I can capture the right group but the \U
doesn't uppercase the capture group.
Any idea? Thanks!
CodePudding user response:
As you discovvered, you're running into the difference between GNU sed and BSD sed; the latter is what ships on macOS. If you install GNU sed (e.g. the Homebrew gnu-sed
package) and use that (probably installed as gsed
), then your original attempt will work.
A more portable solution would be to use perl. Your original sed
expression works unchanged:
$ echo "abcd=efgh" | perl -pe 's/^(.*)=/\U\1\E=/'
ABCD=efgh
Although I would simplify the expression a bit and replace the echo |
with a here-string:
$ perl -pe 's/^[^=]*/\U$&/' <<<'abcd=efgh'
ABCD=efgh
There are other tools you could use, but they don't drop right in with the same syntax as sed like perl does. For example, you could use shell builtins to split the string and then run tr
on the half you want to capitalize:
IFS== read left right <<<abcd=efgh
printf '%s=%s\n' "$(tr a-z A-Z <<<"$left")" "$right"
If you're using zsh, you can use its built-in uppercase expansion instead of tr
:
IFS== read left right <<<abcd=efgh
printf '%s=%s\n' "${(U)left}" "$right"
Newer bash versions can do it, too, but not the one that ships in /bin/ on macOS. You have to install a newer one (for example with Homebrew again), and then this works:
IFS== read left right <<<abcd=efgh
printf '%s=%s\n' "${left^^}" "$right"
CodePudding user response:
Plenty of solutions. Here one using awk
:
awk -F= '{print toupper($1) "=" $2}' <<< 'abcd=efgh'
ABCD=efgh
CodePudding user response:
This might work for you (GNU sed):
sed 'h;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G;s/=.*=/=/' file
Make a copy of the current line.
Translate all lowercase alpha to uppercase alpha.
Append the copy of the original line.
Remove the portion of the two lines from =
to =
and replace it by =
.
Alternative:
sed 's/.*=/\U&/' file
CodePudding user response:
Simply add g
modifier (works with GNU sed):
echo "abcd=efgh" | sed -r 's/^(.*)=/\U\1\E=/g'
CodePudding user response:
With bash
and a regex:
s="abcd=efgh"
[[ "$s" =~ (.*)=(.*) ]] && s="${BASH_REMATCH[1]^^}=${BASH_REMATCH[2]}"
echo "$s"
Output:
ABCD=efgh