0

I am trying to compare two arrays of text files. I keep getting this error

./CompareScript.sh: line 11: read: `../Results/result1.txt[@]': not a valid identifier

Not sure how to properly do this

#!/bin/bash
results=(../Results/*.txt)
correct=(../Correct/*.txt)
j=0
for i in "$results"
do
   while read -r $results[$j]; do
     while read  -r $correct[$j];do
        if [$results[$j]==$correct[$j]] ;  then
          echo "two files are same"
        else
          echo "two files content different"
        fi
     done
   done
   let "j += 1"
done
2
  • I suggest that you comment most of the script out and start off small. Maybe just have the for i ... loop and print the value of i. Does it contain what you expect? If not, then figure out why. If so, then slowly start adding the next piece, testing as you go. Trying to debug the entire script all at once is much more difficult. Sep 8, 2021 at 1:53
  • Think about the nested whiles: Is this really what you want to do, compare each line of the first file with all lines of the other file? If you rather want to compare each line with the corresponding line of the other file, you need only one while with two reads.
    – Philippos
    Sep 8, 2021 at 6:06

1 Answer 1

3

It is rather unclear what you are trying to achieve. If the directories Results and Correct contain matching file names, then you can loop over one of them and generate the other paths:

#!/bin/bash
results=(../Results/*.txt)

for r in "${results[@]}"; do
  diff -sq "$r" "${r/\/Results\//\/Correct\/}"
done

If you want to cross-compare all files from Results with all files form Correct, then that would be a case for nested loops.

#!/bin/bash
results=(../Results/*.txt)
correct=(../Correct/*.txt)

for r in "${results[@]}"; do
  for c in "${correct[@]}"; do
    diff -sq "$r" "$c"
  done
done

A few rather obvious syntax errors:

  • for i in "$results"
    for i in "${results[@]}" to iterate over values
    for i in "${!results[@]}" to iterate over indices
  • $results[$j]"${results[j]}"
  • [$results[$j]==$correct[$j]][[ "${results[j]}" == "${correct[j]}" ]]
  • not exactly an error, but… let "j += 1"((++j))
    — More importantly, your use of i (none at all) and j does not make much sense.
  • to actually read and process a file, line-by-line:
    while IFS= read -r line; do
      printf '%s\n' "$line"
      some_other_command "$line"
    done < "${results[i]}"  # for example
    
    • But why do that↑? If you want to compare files, let diff do it.
1
  • +1, and some comments: 1. i & j are traditionally used for integer iterators. Way back in the days when Fortran was shiny and new and cutting edge, you used them because they WERE integer variables, that's all you could use them for. These days, their use often implies that they're a temporary, throw-array variable you're using for convenience and it has no other meaning than that. Of course, it would make more sense if the OP was actually iterating over the indices. 2. I normally hate using syntax like let but it's IMO more readable/far less ugly than (()) in shell, so I use it there
    – cas
    Sep 8, 2021 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.