Home > Net >  Sorting an array and saving its output in variable
Sorting an array and saving its output in variable

Time:11-22

I have an array array = (Testcase_5_Input_Packets Testcase_3_Input_Packets Testcase_1_Input_Packets Testcase_4_Input_Packets Testcase_2_Input_Packets)

i want to sort its elements and save its sorted contents in an array to be like:
array = Testcase_1_Input_Packets
        Testcase_2_Input_Packets
        Testcase_3_Input_Packets
        Testcase_4_Input_Packets
        Testcase_5_Input_Packets

How do i do that in bash ?

CodePudding user response:

If array elements don't contain newline characters, then this one-liner should do the trick:

readarray -t sorted_array < <(printf '%s\n' "${array[@]}" | sort)

CodePudding user response:

IF your data contains no newlines, then this is straightforward:

rawdata=("Data 1" "Data 3" "Data 2" "Data 4")
tmpfile=/dev/shm/tmp.$$
touch "$tmpfile"
chmod 600 "$tmpfile"
for e in "${rawdata[@]}" 
do
    echo "$e" >> "$tmpfile"
done
sortdata=$(cat "$tmpfile" | sort)
echo "$sortdata" > "$tmpfile"
sortedarray=()
while read line
do
    sortedarray =("$line")
done < "$tmpfile"
rm -f "$tmpfile"

BUT: This will break if an element includes a newline, as that's what sort uses as a delimeter. This is solvable, but you'd need to ID a string that isn't used in your data, trade in-element newlines for that as you write them to the file, and trade them back as you read them out. Once you've ID'd the string, that would look something like:

rawdata=("Data 1" "Data 3" "Data 2" "Data 4")
tmpfile=/dev/shm/tmp.$$
touch "$tmpfile"
chmod 600 "$tmpfile"
for element in "${rawdata[@]}" 
do
    alteration=$(echo "$element" | sed 's/\n/NEWLINEMARKER/g')
    alteration=$(echo "$alteration" | sed 's/NEWLINEMARKER$//g')
    echo "$alteration" >> "$tmpfile"
done
sortdata=$(cat "$tmpfile" | sort)
echo "$sortdata" > "$tmpfile"
sortedarray=()
while read line
do
    element=$(echo "$line" | sed 's/NEWLINEMARKER/\n/g')
    sortedarray =("$element")
done < "$tmpfile"
rm -f "$tmpfile"

Good Coding!

CodePudding user response:

If the strings in the array don't contain any newline character then the most portable bash solution would be:

#!/bin/bash

array=(
    'Testcase_5_Input_Packets'
    'Testcase_3_Input_Packets'
    'Testcase_1_Input_Packets'
    'Testcase_4_Input_Packets'
    'Testcase_2_Input_Packets'
)

IFS=$'\n' read -r -d '' -a array < <(
    printf '%s\n' "${array[@]}" |
    sort -t '_' -k1,1 -k2,2n
)

###########################

printf '%s\n' "${array[@]}"
Testcase_1_Input_Packets
Testcase_2_Input_Packets
Testcase_3_Input_Packets
Testcase_4_Input_Packets
Testcase_5_Input_Packets

CodePudding user response:

If this is your array (spaces as separator!, no newlines in fields)

arr=(Testcase_5_Input_Packets Testcase_3_Input_Packets Testcase_1_Input_Packets Testcase_4_Input_Packets Testcase_2_Input_Packets)

prepare it with sed by introducing newlines

str=($(echo "${arr[@]}" | sed 's/ /\\n/g'))

and finally sort it

arr2=($(echo -e "${str}" | sort))

echo "${arr2[@]}"
Testcase_1_Input_Packets Testcase_2_Input_Packets Testcase_3_Input_Packets Testcase_4_Input_Packets Testcase_5_Input_Packets

OR use a loop

arr3=($(for i in "${arr[@]}";do echo "${i}";done | sort))

echo "${arr3[@]}"
Testcase_1_Input_Packets Testcase_2_Input_Packets Testcase_3_Input_Packets Testcase_4_Input_Packets Testcase_5_Input_Packets
  • Related