Matam Matam - 6 months ago 10
Bash Question

Reading the output of a script in a particular way

So I have a script called

sortByDates
. As you may have guessed, it sorts by dates.
I would like to send a bunch of lines to it(stored in an array in my main script) and read the lines
sortByDates
returns.

Something like this. Say I have:

One 26 One 4 4000 0575342 18.3.2016
Two 27 Two 3 3100 0599342 24.3.2016
Three 28 Three 2 2950 0556742 4.3.2016
Four 29 Four 3 3150 0562342 2.4.2016


Those lines are stored as:

arr[0]=One 26 One 4 4000 0575342 18.3.2016
arr[1]=Two 27 Two 3 3100 0599342 24.3.2016
arr[2]=Three 28 Three 2 2950 0556742 4.3.2016
arr[3]=Four 29 Four 3 3150 0562342 2.4.2016


I would like to send these lines to
sortByDates
, by something like:

$(printf "%s\n" "${arr[@]}" | sortByDates


This what I would have usually be doing, but I want this to be implented a bit different. Something like:

while read -r line; do
sortedLines+=("$line")
done < <(sortByDates < $(printf "%s\n" "${arr[@]}"))


And that's where I stumble. The code above does not work. I fail to understand how to redirect a bunch of lines(or an array) to another script, while I read the new lines(the script's output) to a new array, called
sortedLines
.


The output should look this way:

Three 28 Three 2 2950 0556742 4.3.2016
One 26 One 4 4000 0575342 18.3.2016
Two 27 Two 3 3100 0599342 24.3.2016
Four 29 Four 3 3150 0562342 2.4.2016


So I want
sortedLines
to be:

sortedLines[0]=Three 28 Three 2 2950 0556742 4.3.2016
sortedLines[1]=One 26 One 4 4000 0575342 18.3.2016
sortedLines[2]=Two 27 Two 3 3100 0599342 24.3.2016
sortedLines[3]=Four 29 Four 3 3150 0562342 2.4.2016


Thank you.

Answer
sortedLines=()
while read -r line; do
    sortedLines+=("$line")
done < <(printf "%s\n" "${arr[@]}" | sortByDates)
printf "%s\n" "${sortedLines[@]}"

This produces the output:

Three 28 Three 2 2950 0556742 4.3.2016
One 26 One 4 4000 0575342 18.3.2016
Two 27 Two 3 3100 0599342 24.3.2016
Four 29 Four 3 3150 0562342 2.4.2016

The uses process substitution to feed the results of `` to the while loop.

Aside: The command sortByDates < $(printf "%s\n" "${arr[@]}") tells the shell to provide as input to sortByDates the contents of a file named $(printf "%s\n" "${arr[@]}". That is note what you want.

Debugging

Try running the script under bash -x. Alternatively, try this script:

sortedLines=()
while read -r line; do
    echo line=$line
    sortedLines+=("$line")
    declare -p sortedLines
done < <(printf "%s\n" "${arr[@]}" | sortByDates)
declare -p sortedLines

For me, the above produces:

line=Three 28 Three 2 2950 0556742 4.3.2016
declare -a sortedLines='([0]="Three 28 Three 2 2950 0556742 4.3.2016")'
line=One 26 One 4 4000 0575342 18.3.2016
declare -a sortedLines='([0]="Three 28 Three 2 2950 0556742 4.3.2016" [1]="One 26 One 4 4000 0575342 18.3.2016")'
line=Two 27 Two 3 3100 0599342 24.3.2016
declare -a sortedLines='([0]="Three 28 Three 2 2950 0556742 4.3.2016" [1]="One 26 One 4 4000 0575342 18.3.2016" [2]="Two 27 Two 3 3100 0599342 24.3.2016")'
line=Four 29 Four 3 3150 0562342 2.4.2016
declare -a sortedLines='([0]="Three 28 Three 2 2950 0556742 4.3.2016" [1]="One 26 One 4 4000 0575342 18.3.2016" [2]="Two 27 Two 3 3100 0599342 24.3.2016" [3]="Four 29 Four 3 3150 0562342 2.4.2016")'
declare -a sortedLines='([0]="Three 28 Three 2 2950 0556742 4.3.2016" [1]="One 26 One 4 4000 0575342 18.3.2016" [2]="Two 27 Two 3 3100 0599342 24.3.2016" [3]="Four 29 Four 3 3150 0562342 2.4.2016")'