简体   繁体   中英

Get all variables in bash from text line

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 :)

SOLUTION:

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

Next piece of code will show all variables and its values in fancy style:

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 -rp loop.

You could simply use the below grep command,

$ grep -oP '(?<!\[)(\$[^"\s]+)' file
$text
${items[$i]}
${#items[@]}
$((i+1))

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 

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))"
  1. grep

     $ grep -oP '\\$[^ "]*' file $text ${items[$i]} ${#items[@]} $((i+1)) 
  2. 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 " .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM