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