简体   繁体   中英

Comparing two string arrays in Bash and getting the difference

I've been working on this for hours and I can't seem to figure it out. I'm trying to compare two arrays of strings and using a third array to list the odd ones out. This is what I have:

#! /bin/bash
arr1=( "bww" "jrr" "icp" "bbw" )
arr2=( "bww" "icp" "bbw" )

arr3=("${arr1[@]}")


for j in ${arr2[*]}; do
    for k in ${arr3[*]}; do
        if [ "${arr2[$j]}" == "${arr3[$k]}" ]; then
            arr4[$k]=1
        else
            arr4[$k]=0
        fi
    done
done

for i in ${arr3[*]};do
    if [ ${arr4[$i]} -eq 1 ]; then
        unset ${arr3[$i]}
    fi
done

echo ${arr3[*]}

I feel I've over-complicated it by nesting a second for-loop as well as using a fourth array. When I test this code it just prints out the contents of arr1.

This is the output I'm hoping for:

jrr

Any pointers would be nice, I'm very new to Bash, and I've tried searching other questions, but I can't seem to find what I need. Thanks.

Unsing sort and uniq to extract unique records:

#!/usr/bin/env bash

arr1=( "bww" "jrr" "icp" "bbw" )
arr2=( "bww" "icp" "bbw" )

# Map the null delimited -d '' stream of entries into the array arr3
# from the output of the sub-shell < <(commands) group.
mapfile -d '' arr3 < <(
  # Create a null delimited stream from the entries of both arr1 and arr2
  printf %s\\0 "${arr1[@]}" "${arr2[@]}" |
  
  # Sort the null delimited stream with -z option of sort
  sort -z |
  
  # Extract unique null delimited entries for -z and -u options of uniq
  uniq -zu
)

printf %s\\n "${arr3[@]}"

Alternate method using Bash4+'s associative array to count occurences:

#!/usr/bin/env bash

arr1=( "bww" "jrr" "icp" "bbw" )
arr2=( "bww" "icp" "bbw" )
arr3=()

# Associative array of integers to count occurences of keys
declare -Ai key_count

# Count occurrences of key in arr1 and arr2
for key in "${arr1[@]}" "${arr2[@]}"; do
  key_count[$key]+=1
done

# For each key of key_count Assoc array
for key in "${!key_count[@]}"; do
  # If key occurs only once
  if [ ${key_count[$key]} -eq 1 ]; then
    # Add the key as entry to arr3
    arr3+=("$key")
  fi
done

printf %s\\n "${arr3[@]}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM