Question

all

I got two 2D-array files to read with bash

file1.txt (nx6)

DESC1 DM1 W1 S1 CRITICAL1 GRADE1 #this line dosen't exist
EEE 1x 9 6 Y E2 
AAA X 1 2 Y E2 
C+C X 8 1 Y T1 
HHH 1x 5 5 Y T2 
III X 5 5 Y S1 
JJJ X 5 5 Y S1 
D+ X 2 3 Y T1 

file2.txt (mx3)

DESC2 W2 S2 #this line dosen't exist
AAA 1 2 
EEE 9 5 
FFF 10 7 
GGG 4 9 
III 5 5 
C+C 8 1 
D+ 2 3 
JJJ 5 5 

what I wanna do is to extract the elements inside both files then do some comparisons as following picture:

two muppets http://imgur.com/4479luK.jpg

I really wanna do in green labels is to take one element in $DESC1 and compare with whole elements in ${DESC2[@]}, if it does/dosen't find a element in ${DESC2[@]} then feedback true/false

Here is my work:

#!/bin/bash

clear

ESC=`printf "\033"`

##===================================================================##
##===================================================================##
##========== read information from file1.txt and file1.txt ==========##
##===================================================================##
##===================================================================##

idx1=0

while read -a file1array$idx1; do
    let idx1++
done < file1.txt

idx2=0

while read -a file2array$idx2; do
    let idx2++
done < file2.txt

##===================================================================##
##===================================================================##
##================ start to compare these two files =================##
##===================================================================##
##===================================================================##

for ((i=0; i<idx1; i++)); do
   for ((j=0; j<idx2; j++)); do

        DESC1="file1array$i[0]"
        DM1="file1array$i[1]"
        W1="file1array$i[2]"
        S1="file1array$i[3]"
        CRITICAL1="file1array$i[4]"
        GRADE1="file1array$i[5]"

        DESC2="file2array$j[0]"
        W2="file2array$j[1]"
        S2="file2array$j[2]"

        [ $i == 0 ] && LOSSarray+=(["$j"]="${!DESC2}")

        if [[ "${!GRADE1}" == [E-GT-Z][1-9] && "${!DESC1}" == "${!DESC2}" ]]; then

             W1_Judge=`expr "scale=3; ${!W1} - ${!W2}" | bc`
             S1_Judge=`expr "scale=3; ${!S1} - ${!S2}" | bc`

             [ $W1_Judge != 0 -o $S1_Judge != 0 ] && declare -A jgWS=( ["${!DESC1}"]="WSNG" )

        elif [[ "${!GRADE1}" == [E-GT-Z][1-9] && "$j" == `expr $idx2 - 1` ]]; then

             [[ -z $(echo "${LOSSarray[@]}" | grep -o "${!DESC1}") && "${!CRITICAL1}" != "NULL" ]] && declare -A jgLOSS=( ["${!DESC1}"]="LOSSNG" )

        elif [[ "${!GRADE1}" != [E-GT-Z][1-9] && "${!DESC1}" == "${!DESC2}" ]]; then

             [[ "${!DM1}" == [1-2]x* || "${!DM1}" == "X" ]] && declare -A jgEXTRA=( ["${!DESC1}"]="EXTRANG" )

        fi

    done


    if [[ "${jgWS[${!DESC1}]}" == "WSNG" ]]; then

    echo "${!DESC1}: ${ESC}[0;31mWidth or Space NG${ESC}[0m"

    elif [[ "${jgLOSS[${!DESC1}]}" == "LOSSNG" ]]; then

    echo "${!DESC1}: ${ESC}[0;31mLOSS NG${ESC}[0m"

    elif [[ "${jgEXTRA[${!DESC1}]}" == "EXTRANG" ]]; then

    echo "${!DESC1}: ${ESC}[0;31mEXTRA NG${ESC}[0m"

    else

    echo "${!DESC1}: OK"

    fi


done

It's ok to proceed whole script and output following result:

EEE: Width or Space NG
AAA: OK
C+C: OK
HHH: LOSS NG
III: EXTRA NG
JJJ: EXTRA NG
D+: OK

but if I change file1.txt like this(take the line with "D+" to line1):

D+ X 2 3 Y T1 
EEE 1x 9 6 Y E2 
AAA X 1 2 Y E2 
C+C X 8 1 Y T1 
HHH 1x 5 5 Y T2 
III X 5 5 Y S1 
JJJ X 5 5 Y S1 

I got following result:

D+: syntax error: operand expected (error token is "+")
  1. How can I solve this problem if I don't wanna edit file1.txt?

  2. How can I read the 1st column of file2.txt as a array that I don't need to do it in for-loop?

Was it helpful?

Solution

The problem is that bash throws an error if you try to access an element of an undeclared array using a +. For example:

$ echo "${arr[D+]}"
-bash: D+: syntax error: operand expected (error token is "+")

$ echo "${arr[foo]}" # works

However, if you declare the array first, it works:

$ declare -A arr
$ echo ${arr[D+]} # works

So, you need to make sure that the arrays jgWS, jgLOSS and jgEXTRA have been declared up front, before you access them in your if-statements.

For example, currently the jgWS array is declared only if this condition is met: [ $W1_Judge != 0 -o $S1_Judge != 0 ]. Later on, you try to use the array here: if [[ "${jgWS[${!DESC1}]}" == "WSNG" ]], but it might not have been initialised, in which case it fails.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top