Remove some character in the start and in the end using sed

Viewed 134

I am trying to extract word between "profile " and "]".

my contents

[profile gateway]
[profile personal]
[profile DA]
[profile CX]

for this i have tried

less ~/.aws/config |grep  "\[profile"|sed  -E 's/\[profile(.)//'

which gives

gateway]
personal]
DA]
CX]

I know can add a pipe and us tr to delete last "]" or even cut would do but can someone help me with above sed command with regex to remove last "]"

6 Answers

You can use sed:

sed -n 's/.*\[profile *\([^][]*\).*/\1/p' ~/.aws/config

Details:

  • -n - suppress default line output
  • .*\[profile *\([^][]*\).*/ - find any text, [profile, zero or more spaces, then capture into Group 1 any zero or more chars other than [ and ], and then match the rest of the text
  • \1 - replace with Group 1 value
  • p - print the result of the substitution.

See an online demo:

s='[profile gateway]
[profile personal]
[profile DA]
[profile CX]'
sed -n 's/.*\[profile *\([^][]*\).*/\1/p' <<< "$s"

Output:

gateway
personal
DA
CX

With a GNU grep

grep -oP '(?<=\[profile )[^]]+' ~/.aws/config

The (?<=\[profile )[^]]+ regex matches a location that is immediately preceded with profile string and then matches one or more chars other than ]. -o option makes grep extract the matches only and P enables the PCRE regex syntax.

With awk

You may also use awk:

awk '/^\[profile .*]$/{print substr($2, 0, length($2)-1)}' ~/.aws/config

It will find all lines that start with [profile , and oputput the second field without the last char (that is a ] char that will get omitted).

If you can use grep with -P for a Perl-compatible regular expression:

less ~/.aws/config | grep -oP  "\[profile \K[^][]+(?=])"

The pattern matches:

  • \[profile Match literally
  • \K Forget what is matched so far
  • [^][]+ Match 1+ times any char except [ and ]
  • (?=]) Positive lookahead to assert (not match) ]

For the example content, the output will be

gateway
personal
DA
CX

Keep it simple in awk; by making field separators as either as [profile OR ](as per shown samples) and print the columns as per needed output.

awk -F'\\[profile |\\]' '{print $2}' Input_file

- - extract word between profile and ] means to delete up to profile and from ] on, ie. ^.*profile and ].*$:

$ sed 's/^.*profile \|\].*$//g' file

Output:

gateway
personal
DA
CX

Notice, that if only one boundary is found, it is removed.

Another shorter awk solution:

awk -F '[] ]' '$1 == "[profile" {print $2}' ~/.aws/config

gateway
personal
DA
CX

trying to extract word between "profile " and "]"

Also with awk using as condition that profile is at the end of $1:

awk '$1 ~ /profile$/ {sub(/]$/,"",$2);print $2}' file
gateway
personal
DA
CX
Related