-1

I'm trying to achieve the following results:

I have a command that spits out some env vars to the terminal:

./script will output the following:

AWS_OKTA_PROFILE=xxx
AWS_ACCESS_KEY_ID=xxx
AWS_SECRET_ACCESS_KEY=xx
AWS_SECURITY_TOKEN=xx
AWS_SESSION_TOKEN=xx

I want to write this to an output file in another location to be almost the same except like this (but only before the equal sign)

[default]
aws_okta_profile=xxx
aws_access_key_id=xxx
aws_secret_access_key=xx
aws_security_token=xx
aws_session_token=xx

Notice, I'm also prepending [default] to the file.

Thanks!

Ryan
  • 57
  • 1
  • 9

2 Answers2

3

In addition to sed, awk also provides a simple solution. You can use the '=' as the field-separator and simply convert the first field to lowercase with tolower() if the record contains an '=' sign. (or you can check NF>1 to check you have more than one field) The 1 at the end of the rule is simply short-hand for print. Putting it altogether, you can use

awk -F= -v OFS='=' '/=/{$1=tolower($1)}1' file

Example Use/Output

With your input in the file file, you would get:

$ awk -F= -v OFS='=' '/=/{$1=tolower($1)}1' file
[default]
aws_okta_profile=xxx
aws_access_key_id=xxx
aws_secret_access_key=xx
aws_security_token=xx
aws_session_token=xx

awk does not have an edit in-place mechanism (except by non-standard extension), so simply redirect the output to a new file, e.g.

$ awk -F= -v OFS='=' '/=/{$1=tolower($1)}1' file > newfile
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
1

The search and replace with lowercase can be done with sed like this:

#!/usr/bin/env -S sed -f
s/\([^=]\+\)=\([^=]\+\)/\L\1=\E\2/
  • s/\([^=]\+\)=\([^=]\+\)/: search regex pattern:
    • \([^=]\+\): capture group of 1 or more characters not an = sign,
    • =: followed by an = sign,
    • \([^=]\+\): followed by another captured group of 1 or more characters not an = sign.
  • /\L\1=\E\2/: Replace matches with this:
    • \L\1: Lowercase the captured group 1,
    • =: followed by an = sign,
    • \E\2: followed by captured group 2 with case unchanged.
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
  • 1
    The `\L` escape is not very portable, though I guess this will work with GNU `sed`. – tripleee Jul 31 '20 at 19:39
  • Im getting: env | grep -i aws | s/\([^=]\+\)=\([^=]\+\)/\L\1=\E\2/ zsh: no matches found: s/([^=]+)=([^=]+)/L1=E2/ [1] 24128 done env | 24129 broken pipe grep --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn,.idea,.tox} -i aws – Ryan Jul 31 '20 at 19:49
  • `grep -i aws | sed 's/([^=]\+)=([^=]\+)/\L\1=\E\2/' > newfile` – David C. Rankin Jul 31 '20 at 20:04
  • 2
    This solution supposes that you save this in a file and make it executable. On the command line, you'd prepend `sed` and put single quotes around the script. (You could easily factor out the `grep` too; `sed '/[Aa][Ww][Ss]/s/\([^=]...'` (there is no simple flag to make `sed` match case-insensitively, though maybe GNU has that too). – tripleee Jul 31 '20 at 20:04
  • @Ryan this is the issue with asking for code without having done some research. You end-up copy-pasting code you don't understand, and it cannot work, as you cannot ride a horse's tail if it is not attached to the horse. – Léa Gris Jul 31 '20 at 20:04
  • 1
    Also, one of the perils of attempting to answer questions which don't demonstrate any effort; you can't gauge the level of the OP. – tripleee Jul 31 '20 at 20:06
  • @tripleee I made the solution unusable as a copy-paste deliberately as a bottle at the sea to invite Ryan to do some research and understand the code before using it. – Léa Gris Jul 31 '20 at 20:19