I've got almost the same question as here.
I have an array which contains aa ab aa ac aa ad
, etc. Now I want to select all unique elements from this array. Thought, this would be simple with sort | uniq
or with sort -u
as they mentioned in that other question, but nothing changed in the array... The code is:
echo `echo "${ids[@]}" | sort | uniq`
What am I doing wrong?
Using tr, the numbers are split to individual lines, and sort is used to sort the numbers(-n) and remove the duplicate ones(-u). You can leave off the | xargs . Because of the way the shell handles multi-line output from a $(…) command, L=$(echo $L | tr ' ' '\n' | sort –u) is enough.
How to Echo a Bash Array? To echo an array, use the format echo ${Array[0]}. Array is your array name, and 0 is the index or the key if you are echoing an associative array. You can also use @ or * symbols instead of an index to print the entire array.
A bit hacky, but this should do it:
echo "${ids[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '
To save the sorted unique results back into an array, do Array assignment:
sorted_unique_ids=($(echo "${ids[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
If your shell supports herestrings (bash
should), you can spare an echo
process by altering it to:
tr ' ' '\n' <<< "${ids[@]}" | sort -u | tr '\n' ' '
A note as of Aug 28 2021:
According to ShellCheck wiki 2207 a read -a
pipe should be used to avoid splitting. Thus, in bash the command would be:
IFS=" " read -r -a ids <<< "$(echo "${ids[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
or
IFS=" " read -r -a ids <<< "$(tr ' ' '\n' <<< "${ids[@]}" | sort -u | tr '\n' ' ')"
Input:
ids=(aa ab aa ac aa ad)
Output:
aa ab ac ad
Explanation:
"${ids[@]}"
- Syntax for working with shell arrays, whether used as part of echo
or a herestring. The @
part means "all elements in the array"tr ' ' '\n'
- Convert all spaces to newlines. Because your array is seen by shell as elements on a single line, separated by spaces; and because sort expects input to be on separate lines.sort -u
- sort and retain only unique elementstr '\n' ' '
- convert the newlines we added in earlier back to spaces.$(...)
- Command Substitution tr ' ' '\n' <<< "${ids[@]}"
is a more efficient way of doing: echo "${ids[@]}" | tr ' ' '\n'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With