Reputation: 414
I want to read the output of a psql query produced with --field-separator-zero into an array inside my bash script. The best I have tried was the following:
psql -w -t --quiet --no-align --field-separator-zero -c $'select nickname,first_name,last_name,email from users' | while IFS= read -d '' -a USERS; do
echo ${USERS[0]} ${USERS[1]} ${USERS[2]} ${USERS[3]};
done;
The above would return each field of a row as a new array. Changing the delimiter to anything else would make the process work, but the problem is the nickname field might contain any character, so I'm forced to use the safe NUL char as a delimiter. Is there any way to do this ?
Upvotes: 0
Views: 806
Reputation: 295716
I'm assuming here that nickname is a unique key; make the appropriate modifications if a different field should be used in that role.
The below code reads the data into a series of associative arrays, and emits each row in turn.
Note that associative arrays are a Bash 4 feature; if you're on Mac OS, which ships 3.2, use MacPorts or a similar tool to install a modern release.
declare -A first_names=( ) last_names=( ) emails=( )
while IFS= read -r -d '' nickname && \
IFS= read -r -d '' first_name && \
IFS= read -r -d '' last_name && \
IFS= read -r -d '' email; do
first_names[$nickname]=$first_name
last_names[$nickname]=$last_name
emails[$nickname]=$email
done < <(psql ...)
echo "Found users: "
for nickname in "${!emails[@]}"; do
printf 'nickname - %q\n' "$nickname"
printf 'email - %q\n' "${emails[$nickname]}"
printf 'first name - %q\n' "${first_names[$nickname]}"
printf 'last name - %q\n' "${last_names[$nickname]}"
echo
done
This technique is described in BashFAQ #1 -- search for -print0
to find its mention.
Upvotes: 2