Reputation: 1168
In the book "The Linux Command Line" the author presents an example of sorting an array:
arr=(f e d c b a)
arr_sorted=($(for i in "${arr[@]}"; do echo $i; done | sort))
The output from the for
loop (which prints all subsequent array values with echo
) is pipelined to sort
.
On the other hand, in another chapter the author presents a similar example but exploiting a Bash "group command" which is denoted by surrounding braces { }
(I minimized his script preserving the idea):
declare -A arr # an associative array
arr["key0"]=val0
arr["key2"]=val2
arr["key1"]=val1
{ for i in "${!arr[@]}"; do
printf "%s: %s\n" "$i" "${arr["$i"]}"
done } | sort
The author's point is: "(...) Also note that the entire loop is enclosed in braces thus forming a group command. This permits the entire output of the loop to be piped into the sort command."
However I ran this script (both the book's original and the minimized) both with and without "group command" braces and they all worked perfectly the same - the output is equivalent.
So why the author insists on using a group command in the above case although it works perfectly OK without it and even he himself showed a similar working version (with arr_sorted
) in the previous chapter? Maybe I'm missing something else here.
Upvotes: 0
Views: 637
Reputation: 532238
The command group would be useful if you wanted to combine the output of two or more separate commands. For example,
{
for i in "${!arr[@]}"; do
printf "%s: %s\n" "$i" "${arr["$i"]}"
done
while IFS=, read -r a b; do
printf "%s: %s\n" "$a" "$b"
done < some_file.txt
} | sort
But as you noticed, a for
loop is already a single command, so there's no point in wrapping it inside another compound command to collect its output for a pipe.
A command group is especially nice for avoiding repeated redirections, which requires repeated opening and closing of files. Code like
echo ... > some_file.txt
echo ... >> some_file.txt
echo ... >> some_file.txt
echo ... >> some_file.txt
echo ... >> some_file.txt
can be replaced with
{
echo ...
echo ...
echo ...
echo ...
echo ...
} > some_file.txt
which opens some_file.txt
once, not five times.
Upvotes: 1
Reputation: 141768
There is no difference between putting a single command in {
}
braces or not.
The:
{ for i in "${!arr[@]}"; do
printf "%s: %s\n" "$i" "${arr["$i"]}"
done } | sort
is equivalent to:
for i in "${!arr[@]}"; do
printf "%s: %s\n" "$i" "${arr["$i"]}"
done | sort
Ex.:
{ { { { { echo a; }; }; }; }; }
is just echo a
Upvotes: 1