branquito
branquito

Reputation: 4034

saving variables obtained from awk, for later use (bash)

Having credentials file like this one:

db: db_name
user: username
password: password

After this command has been run:

awk '$1 ~ /db:|user:|password:/ { print $2 }' credentials \
| while read line; do c+=($line); done;

, I won't have a possibility to echo out my ${c[@]} array, because pipe process has terminated, and variable is gone. How would I manage to save that after while loop is terminated, so that I could use elements of that c array, as credentials for example in following command:

mysql -u ${c[1]} -p${c[2]} ${c[0]} < file.sql

Upvotes: 0

Views: 1287

Answers (5)

user1139082
user1139082

Reputation: 1

credentials.txt (text file):

db: db_name
user: username
password: password

You can just assign the variables in awk- then after processing all rows in the the credentials file (or stdin), print out the command you want to run and pipe it to the shell to execute it.

cat credentials.txt|awk '/db/{db=$2} /username/{username=$2} /password/{password=$2} \
END{print "mysql -u "username" -p "password" "db" < file.sql"}' |sh

That will print: mysql -u username -p password db_name < file.sql

Then pass it to the shell and execute the query.

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 203189

You don't need a loop at all:

$ c=( $( awk '$1 ~ /db:|user:|password:/ { print $2 }' file ) )
$ echo "${c[0]}"
db_name
$ echo "${c[1]}"
username
$ echo "${c[2]}"
password

Upvotes: 3

Tom Fenech
Tom Fenech

Reputation: 74596

You could just do the whole thing in awk:

$ awk -F ': ' '{a[$1]=$2}END{system("echo mysql -u " a["user"] " -p" a["password"] " " a["db"] " < file.sql")}' file

Upvotes: 1

anubhava
anubhava

Reputation: 784938

Don't use pipe since it creates a sub process and all the variable created under it will not be available in parent shell. Use process substitution instead:

while read -r line; do 
    c+=($line)
done < <(awk '$1 ~ /db:|user:|password:/ { print $2 }' credentials)

Upvotes: 3

P.P
P.P

Reputation: 121357

Instead of redirecting it to pipe you could do:

while read line; do 
  c+=($line)
done <<<"$(awk '$1 ~ /db:|user:|password:/ { print $2 }' credentials)"

Now the array c will be available even after the loop exited.

However, you could directly read from the file credentials instead of using awk as you seem to be using awk only for splitting the line, which you could in bash itself:

while read line; do 
  line=${line##*:}
  c+=($line)
done <credentials

Upvotes: 2

Related Questions