Reputation: 2028
I have a file with the following format:
text${v1}text${v2}etc
How do I extract all variables names from it using bash?
Expected output is: v1
v2
Upvotes: 3
Views: 267
Reputation: 2865
echo 'text${v1}text${v2}etc' | mawk 'gsub(OFS"+", __, $!(NF = NF)) + \ gsub("^"(__) "|"(__)"$", _)^_ + gsub(__," /\f\b\b/ ")' \ __='\300' \ FS='(^[^$}{]*)?[$][{]|[}][^}{$]*|[\301]+' OFS='\301'
v1 /
/ v2
Upvotes: 1
Reputation: 163477
An alternative with grep and -P
to enable Perl-compatible regular expressions:
grep -oP '\${\K[^}]*(?=})' file
The pattern matches:
\$
Match $
{
Match literally\K
Forget what is matched until now[^}]*
Match optional repetitions of any char except }
(?=})
Positive lookahead, assert }
to the rightOutput
v1
v2
Or using gnu awk
with a capture group in the regex ([^}]*)
and print that group 1 value using a[1]
(same looping mechanism as the answer of @RavinderSingh13)
awk '
{
while(match($0,/\${([^}]*)}/, a)){
print a[1]
$0=substr($0,RSTART+RLENGTH)
}
}
' file
Upvotes: 4
Reputation: 11237
Using sed
sed -E 's/[^$]*\$\{([^}]*)}|[[:alpha:] ]+$/\1 /g' input_file
v1 v2
Upvotes: 4
Reputation: 133650
1st solution: Within single GNU awk
you could try following code. Written and tested with shown samples only. Simple explanation would be, setting RS(record separator) as \\${[^}]*}
and then in main program substituting values like ${
and }
from RT and printing only required values as per requirement.
awk -v RS='\\${[^}]*}' 'RT{gsub(/^\${|}$/,"",RT);print RT}' Input_file
2nd solution: With any awk
please try following awk
code.
awk '
{
while(match($0,/\${[^}]*}/)){
print substr($0,RSTART+2,RLENGTH-3)
$0=substr($0,RSTART+RLENGTH)
}
}
' Input_file
Upvotes: 6
Reputation: 785641
Using simple grep + sed
:
grep -o '\${[^}]*}' file | sed -E 's/^\${|}$//g'
v1
v2
Here:
- `grep` matches and prints `${...}` strings
- `sed` removes `\${` and `}` from output
Upvotes: 5