Reputation: 941
Suppose I have a text line like
echo -e "$text is now set for ${items[$i]} and count is ${#items[@]} and this number is $((i+1))"
I need to get all variables (for example, using sed) so that after all I have list containing: $text, ${items[$i]}, $i, ${#items[@]}, $((i+1)).
I am writing script which have some complex commands and before executing each command it prompts it to user. So when my script prompts command like "pacman -S ${softtitles[$i]}" you can't guess what this command is actually does. I just want to add a list of variables used in this command below and it's values. So I decided to do it via regex and sed, but I can't do it properly :/
UPD: It can be just a string like echo "$test is 'ololo', ${items[$i]} is 'today', $i is 3", it doesn't need to be list at all and it can include any temporary variables and multiple lines of code. Also it doesn't have to be sed :)
echo $m | grep -oP '(?<!\[)\$[{(]?[^"\s\/\047.\\]+[})]?' | uniq > vars
$m
- our line of code with several bash variables, like "This is $string with ${some[$i]} variables"
uniq
- if we have string with multiple same variables, this will remove dublicates
vars
- temporary file to hold all variables found in text string
if [ ! "`cat vars`" == "" ]; then
while read -r p; do
value=`eval echo $p`
Style=`echo -e "$Style\n\t$Green$p = $value$Def"`
done < vars
fi
$Style
- predefined variable with some text (title of the command)
$Green
, $Def
- just tput
settings of color (green -> text -> default)
Green=`tput setaf 2`
Def=`tput sgr0`
$p
- each line of vars
file (all variables one by one) looped by while read -r p
loop.
Upvotes: 2
Views: 458
Reputation: 3380
A few approaches, I tested each of them on file
which contains
echo -e "$text is now set for ${items[$i]} and count is ${#items[@]} and this number is $((i+1))"
grep
$ grep -oP '\$[^ "]*' file
$text
${items[$i]}
${#items[@]}
$((i+1))
perl
$ perl -ne '@f=(/\$[^ "]*/g); print "@f"' file
$text ${items[$i]} ${#items[@]} $((i+1))
or
$ perl -ne '@f=(/\$[^ "]*/g); print join "\n",@f' file
$text
${items[$i]}
${#items[@]}
$((i+1))
The idea is the same in all of them. They will collect the list of strings that start with a $
and as many subsequent characters as possible that are neither spaces nor "
.
Upvotes: 1
Reputation: 174796
You could simply use the below grep command,
$ grep -oP '(?<!\[)(\$[^"\s]+)' file
$text
${items[$i]}
${#items[@]}
$((i+1))
Upvotes: 2
Reputation: 5092
I'm not sure its perfect , but it will help for you
sed -r 's/(\$[^ "]+)/\n\1\n/g' filename | sed -n '/^\$/p'
Explanation :
(\$[^ "]+) - Match the character $ followed by any charter until whitespace or double quote.
\n\1\n - Matched word before and after put newlines ( so the variable present in separate line ) .
/^\$/p - start with $ print the line like print variable
Upvotes: 1