Reputation: 141
The read
command in the below code is parsing only the first line from the input. But it works fine when the IFS
is set to comma or any other symbol other than newline.
u="*
john
dan"
IFS=$'\n';read -ra q <<< "$u"
for j in "${q[@]}"
do
echo "drop user $j"
done
The output is just:
drop user *
What I'm expecting is:
drop user *
drop user john
drop user dan
Note that the first item in the input is an asterisk. So if I use the below code for splitting, then the asterisk gets expanded to the list of files in the directory.
IFS=$'\n'; q=($u); unset IFS;
Output:
drop user abc
drop user test.sh
drop user john
drop user dan
What is wrong with the above code? How to correct it to get the intended output?
Upvotes: 1
Views: 361
Reputation: 52102
read
reads just a single line from standard input. If you have Bash 4.0 or newer, you can use readarray
:
readarray -t q <<< "$u"
after which your array looks like this:
$ declare -p q
declare -a q=([0]="*" [1]="john" [2]="dan")
readarray
(and its alias mapfile
) defaults to delimiting array elements with newlines, so the IFS
assignment can be dropped. Bash 4.4 introduced a -d
option to use a delimiter other than newline, but that's not required here.
Once your elements are in an array, you can print your commands with a single printf
statement as follows:
printf 'drop user %s\n' "${q[@]}"
Upvotes: 3
Reputation: 784898
You can just do this while read
loop:
u="*
john
dan"
while IFS= read -r user; do
echo "drop user $user"
done <<< "$u"
Output:
drop user *
drop user john
drop user dan
Upvotes: 3