LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   bash - merging strings (perhaps with sort | uniq) (https://www.linuxquestions.org/questions/linux-newbie-8/bash-merging-strings-perhaps-with-sort-%7C-uniq-844519/)

cmbouchard 11-16-2010 12:48 AM

bash - merging strings (perhaps with sort | uniq)
 
Hi everyone,

I've used this site for a while an unregistered user. This is my first post.

I have multiple strings (eg. say two, firstLIST=(0 1 2) and secondLIST=(2 3)) and want to create a single string composed of their unique sorted elements. For the sample strings above, I'd like to build masterLIST=(0 1 2 3).

I suppose I could write the elements of firstLIST and secondLIST to files

Code:

echo ${firstLIST[@]} > firstFILE
echo ${secondLIST[@]} > secondFILE

then use

Code:

sort firstFILE secondFILE | uniq > masterFILE
as this gives me a file populated with the elements I'm after, but I'm not sure how to read the elements back into masterLIST... and it doesn't seem "right" to create files to accomplish this. Is there a way to do this by manipulating the strings ${firstLIST[@]} and ${secondLIST[@]} directly?

The closest I've come (not close at all) is

Code:

masterLIST=${firstLIST[@]}" "${secondLIST[@]}
but masterLIST built this way has only one element

Code:

$echo ${masterLIST[@]}
0 1 2 2 3
$echo ${#masterLIST[@]}
1

and I don't have access to the individual digits to then try to figure out how to remove duplicates.

Thanks for any help,
Chris

catkin 11-16-2010 01:10 AM

Here's one solution (OK for the simple numbers in the example, would need tweaking if the lines contained whitespace):
Code:

#!/bin/bash

# Load arrays
firstLIST=(0 1 2)
secondLIST=(2 3)
masterLIST=( ${firstLIST[*]} ${secondLIST[*]} )

# Generate results array
while read
do
    newLIST+=( $REPLY )
done <<< $(
        for (( i=0; i < ${#masterLIST[*]}; i++ ))
        do
            echo "${masterLIST[i]}"
        done | sort | uniq
    )

# Show results
for (( i=0; i < ${#newLIST[*]}; i++ ))
do
    echo "$i: ${newLIST[i]}"
done


grail 11-16-2010 01:40 AM

Another alternative:
Code:

#!/bin/bash

# Load arrays
firstLIST=(0 1 2)
secondLIST=(2 3)
tmpLIST=( ${firstLIST[*]} ${secondLIST[*]} )

for x in ${tmpLIST[*]}
do
    for (( i=0; i< ${#newLIST[*]}; i++))
    do
        (( x == ${newLIST[i]} )) && continue 2
    done

    newLIST+=($x)
done

echo "${newLIST[*]}"


grail 11-16-2010 04:37 AM

And another slight change I thought of on the way home :)
Code:

#!/bin/bash

# Load arrays
firstLIST=(0 1 2)
secondLIST=(2 3)
tmpLIST=( ${firstLIST[*]} ${secondLIST[*]} )

for x in ${tmpLIST[*]}
do
    [[ ${newLIST[*]} =~ " $x " ]] || newLIST+=($x)
done

echo "${newLIST[*]}"


cmbouchard 11-16-2010 11:21 PM

solutions for sorting unique elements of bash arrays
 
grail and catkin,

Thanks for your solutions! I'd cobbled together the following inferior solution of writing out to files, working with the files, then reading into an array,

Code:

count1=${#firstLIST[@]}
count2=${#secondLIST[@]}

for (( i=0; i<$count1; i++ )); do
  echo ${firstLIST[$i]} >> tmp_file
done
for (( i=0; i<$count2; i++ )); do
  echo ${secondLIST[$i]} >> tmp_file
done

sort -u tmp_file > tmp_file
masterLIST=( `cat tmp_file` )

but much prefer how you have worked directly with the arrays.

Thanks again,
Chris


All times are GMT -5. The time now is 09:19 AM.