# 2D Array using AWK - pls help

**URL:** <https://community.unix.com/t/2d-array-using-awk-pls-help/165386>\
**Category:** Shell Programming and Scripting\
**Created:** [September 21, 2006, 2:06am UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386 "2006-09-21T02:06:56Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Raynon](https://community.unix.com/letter_avatar/raynon/32/5_5575768a8748004e209b776fc1b2916d.png) [@Raynon](https://community.unix.com/u/Raynon)\
**Post date:** [September 21, 2006, 2:06am UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/1 "2006-09-21T02:06:56Z")

</div>

Hi, i want to write a script using AWK to compare the difference between 2 text file using 2 dimensional array. The script should compare each and every symbol display in the 5 by 5 matrix.  
The output should display the coordinates (x,y) of where the difference lies, and displays what is the symbol at Text 1 and symbol at Text 2. Pls help. Thanks

Text 1:

05 \*  
04 \* \* \*  
03 \*\* \* \* \*  
02 \* \* \*  
01 \*  
0 0 0 0 0  
1 2 3 4 5

Text 2:

05 &  
04 \* \* \*  
03 \*\* \* \* \*  
02 \* \* \*  
01 \*  
0 0 0 0 0  
1 2 3 4 5

Here, we should be expecting the below output:

Coordinates = (03,05)  
Symbol at Text 1 = \*  
Symbol at Text 2 = &

---

<div class="post-metadata">

**Author:** ![aigles](https://community.unix.com/user_avatar/community.unix.com/aigles/32/118_2.png) [@aigles](https://community.unix.com/u/aigles)\
**Post date:** [September 21, 2006, 3:35am UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/2 "2006-09-21T03:35:16Z")

</div>

Try and adapt the following awk program cmp.awk :

```nohighlight
BEGIN {
   yy[1] = yy[2] = 5;
   for (x=1; x<=5; x++)
      for (y=1; y<=5; y++)
         array[1, x, y] = array[2, x, y] = " ";
}
FNR > 5 {
   next;
}
{
   arr = (NR == FNR ? 1 : 2);
   y = yy[arr];
   $0 = $0 " ";
   for (x=1; x<=5; x++) 
      array[arr, x, y] = substr($0, x, 1);
   yy[arr] -= 1;
}
END {
   for (x=1; x<=5; x++)
      for (y=1; y<=5; y++)
         if (array[1, x, y] != array[2, x, y]) {
            printf("Coordinates = (%02d,%02d)\n", x, y);
            printf("Symbol at Text 1 = %s\n", array[1, x, y]);
            printf("Symbol at Text 2 = %s\n", array[2, x, y]);
         }
}

```

The execution of the program gives :

```nohighlight
$ cat text1
*
* * *
* * * * *
* * *
*
$ cat text2
&
* * *
* * * * *
* * *
*
$ awk -f cmp.awk text1 text2
Symbol at Text 1 = *
Symbol at Text 2 = &
$

```

Jean-Pierre.

---

<div class="post-metadata">

**Author:** ![happyv](https://community.unix.com/letter_avatar/happyv/32/5_5575768a8748004e209b776fc1b2916d.png) [@happyv](https://community.unix.com/u/happyv)\
**Post date:** [September 21, 2006, 3:53am UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/3 "2006-09-21T03:53:38Z")

</div>

> [@aigles](#):
>
> Try and adapt the following awk program cmp.awk :
> 
> ```plaintext
> BEGIN {
> yy[1] = yy[2] = 5;
> for (x=1; x<=5; x++)
> for (y=1; y<=5; y++)
> array[1, x, y] = array[2, x, y] = " ";
> }
> FNR > 5 {
> next;
> }
> {
> arr = (NR == FNR ? 1 : 2);
> y = yy[arr];
> $0 = $0 " ";
> for (x=1; x<=5; x++) 
> array[arr, x, y] = substr($0, x, 1);
> yy[arr] -= 1;
> }
> END {
> for (x=1; x<=5; x++)
> for (y=1; y<=5; y++)
> if (array[1, x, y] != array[2, x, y]) {
> printf("Coordinates = (%02d,%02d)\n", x, y);
> printf("Symbol at Text 1 = %s\n", array[1, x, y]);
> printf("Symbol at Text 2 = %s\n", array[2, x, y]);
> }
> }
> 
> ```
> 
> The execution of the program gives :
> 
> ```plaintext
> $ cat text1
> *
> * * *
> * * * * *
> * * *
> *
> $ cat text2
> &
> * * *
> * * * * *
> * * *
> *
> $ awk -f cmp.awk text1 text2
> Symbol at Text 1 = *
> Symbol at Text 2 = &
> $
> 
> ```
> 
> Jean-Pierre.

which value is belong to file - test1 and test2?

---

<div class="post-metadata">

**Author:** ![Raynon](https://community.unix.com/letter_avatar/raynon/32/5_5575768a8748004e209b776fc1b2916d.png) [@Raynon](https://community.unix.com/u/Raynon)\
**Post date:** [September 21, 2006, 4:21am UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/4 "2006-09-21T04:21:43Z")

</div>

> [@aigles](#):
>
> Try and adapt the following awk program cmp.awk :
> 
> ```plaintext
> BEGIN {
> yy[1] = yy[2] = 5;
> for (x=1; x<=5; x++)
> for (y=1; y<=5; y++)
> array[1, x, y] = array[2, x, y] = " ";
> }
> FNR > 5 {
> next;
> }
> {
> arr = (NR == FNR ? 1 : 2);
> y = yy[arr];
> $0 = $0 " ";
> for (x=1; x<=5; x++) 
> array[arr, x, y] = substr($0, x, 1);
> yy[arr] -= 1;
> }
> END {
> for (x=1; x<=5; x++)
> for (y=1; y<=5; y++)
> if (array[1, x, y] != array[2, x, y]) {
> printf("Coordinates = (%02d,%02d)\n", x, y);
> printf("Symbol at Text 1 = %s\n", array[1, x, y]);
> printf("Symbol at Text 2 = %s\n", array[2, x, y]);
> }
> }
> 
> ```
> 
> The execution of the program gives :
> 
> ```plaintext
> $ cat text1
> *
> * * *
> * * * * *
> * * *
> *
> $ cat text2
> &
> * * *
> * * * * *
> * * *
> *
> $ awk -f cmp.awk text1 text2
> Symbol at Text 1 = *
> Symbol at Text 2 = &
> $
> 
> ```
> 
> Jean-Pierre.

Hi Jean, it works!! Thanks.... but i hav some question about the codes...  
array[1, x, y] = array[2, x, y] = " "; =\> is this a 3 D array since there are 3 indexes?

arr = (NR == FNR ? 1 : 2);

yy[arr] -= 1

=\> what are these sentences trying to do ?

Thanks in advance

---

<div class="post-metadata">

**Author:** ![Raynon](https://community.unix.com/letter_avatar/raynon/32/5_5575768a8748004e209b776fc1b2916d.png) [@Raynon](https://community.unix.com/u/Raynon)\
**Post date:** [September 21, 2006, 5:22am UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/5 "2006-09-21T05:22:11Z")

</div>

> [@raynon](#):
>
> Hi Jean, it works!! Thanks.... but i hav some question about the codes...  
> array[1, x, y] = array[2, x, y] = " "; =\> is this a 3 D array since there are 3 indexes?
> 
> arr = (NR == FNR ? 1 : 2);
> 
> yy[arr] -= 1
> 
> =\> what are these sentences trying to do ?
> 
> Thanks in advance

I reallise that when i add on another difference to Text 2 , the correct coordinate could not be captured any more.

Text 2:

&

- 
  - \*

- 
  - ^ \* \*

- 
  - \*  
\*

Output:  
$ nawk -f expert\_awk text1 text2  
Coordinates = (01,05)  
Symbol at Text 1 = \*  
Symbol at Text 2 = &  
Coordinates = (05,03) =\> wrong coordinate!!  
Symbol at Text 1 = \*  
Symbol at Text 2 = ^

Can this script be used for any 5 by 5 matrix comparison or is this just limited to this particular orientation of the matrix ?

---

<div class="post-metadata">

**Author:** ![aigles](https://community.unix.com/user_avatar/community.unix.com/aigles/32/118_2.png) [@aigles](https://community.unix.com/u/aigles)\
**Post date:** [September 21, 2006, 9:37am UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/6 "2006-09-21T09:37:07Z")

</div>

My awk program considers single char values with no separator in the matrix.  
I modify it for space separated values in the matrix (not limited to single caracters).

```nohighlight
BEGIN {
   yy[1] = yy[2] = 5;
   for (x=1; x<=5; x++)
      for (y=1; y<=5; y++)
         array[1, x, y] = array[2, x, y] = " ";
}
FNR > 5 {
   next;
}
{
   arr = (NR == FNR ? 1 : 2);
   y = yy[arr];
   $0 = $0 " ";
   for (x=1; x<=5; x++) 
      array[arr, x, y] =$x;
   yy[arr] -= 1;
}
END {
   for (x=1; x<=5; x++)
      for (y=1; y<=5; y++)
         if (array[1, x, y] != array[2, x, y]) {
            printf("Coordinates = (%02d,%02d)\n", x, y);
            printf("Symbol at Text 1 = %s\n", array[1, x, y]);
            printf("Symbol at Text 2 = %s\n", array[2, x, y]);
         }
}

```

Now, some explanations :

array[1, x, y] = array[2, x, y] = " ";  
array is a 3D array.  
array{1] is for text1 and array[2] for text2.  
This statement also can be written :  
array[1, x, y] = " ";  
array[2, x, y] = " ";

arr = (NR == FNR ? 1 : 2);  
The ( test ? value1 : value2 ) syntax is the equiv to:  
if ( test )  
return value1  
else  
return value2

yy[arr] -= 1  
a short cut for  
yy[arr] = y[arr] - 1

Jean-Pierre.

---

<div class="post-metadata">

**Author:** ![ghostdog74](https://community.unix.com/letter_avatar/ghostdog74/32/5_5575768a8748004e209b776fc1b2916d.png) [@ghostdog74](https://community.unix.com/u/ghostdog74)\
**Post date:** [September 21, 2006, 10:43am UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/7 "2006-09-21T10:43:30Z")

</div>

Here's an alternative in Python:

file1 :

05 \*  
04 \* \* \*  
03 \*\* \* \* \*  
02 \* \* \*  
01 \*  
0 0 0 0 0  
1 2 3 4 5

file2:

05 &  
04 \* \* \*  
03 \*\* \* \* \*  
02 # \* $  
01 \*  
0 0 0 0 0  
1 2 3 4 5

```nohighlight
text1 = open("file1.txt").readlines()
text2 = open("file2.txt").readlines()
for y in range(len(text1)): ## y-coordinates
	if text1[y] != text2[y]:
		t1_splitted = text1[y].split()
		t2_splitted = text2[y].split()		
		for x in range(5): ## x-coordinates
			try:
				if t1_splitted[x] != t2_splitted[x]:					 
					coordinates = y,x #get coordinates
					print "Coordinates" , coordinates
					print "Symbol at text 1 %s" % t1_splitted[x] 
					print "Symbol at text 2 %s\n" % t2_splitted[x]
					print "-" * 50
			except:pass

```

Output:

```nohighlight
/home> python test.py
Coordinates (0, 1)
Symbol at text 1 *
Symbol at text 2 &

--------------------------------------------------
Coordinates (3, 1)
Symbol at text 1 *
Symbol at text 2 #

--------------------------------------------------
Coordinates (3, 3)
Symbol at text 1 *
Symbol at text 2 $

--------------------------------------------------

```

---

<div class="post-metadata">

**Author:** ![Raynon](https://community.unix.com/letter_avatar/raynon/32/5_5575768a8748004e209b776fc1b2916d.png) [@Raynon](https://community.unix.com/u/Raynon)\
**Post date:** [September 21, 2006, 10:07pm UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/8 "2006-09-21T22:07:26Z")

</div>

> [@aigles](#):
>
> My awk program considers single char values with no separator in the matrix.  
> I modify it for space separated values in the matrix (not limited to single caracters).
> 
> ```plaintext
> BEGIN {
> yy[1] = yy[2] = 5;
> for (x=1; x<=5; x++)
> for (y=1; y<=5; y++)
> array[1, x, y] = array[2, x, y] = " ";
> }
> FNR > 5 {
> next;
> }
> {
> arr = (NR == FNR ? 1 : 2);
> y = yy[arr];
> $0 = $0 " ";
> for (x=1; x<=5; x++) 
> array[arr, x, y] =$x;
> yy[arr] -= 1;
> }
> END {
> for (x=1; x<=5; x++)
> for (y=1; y<=5; y++)
> if (array[1, x, y] != array[2, x, y]) {
> printf("Coordinates = (%02d,%02d)\n", x, y);
> printf("Symbol at Text 1 = %s\n", array[1, x, y]);
> printf("Symbol at Text 2 = %s\n", array[2, x, y]);
> }
> }
> 
> ```
> 
> Now, some explanations :
> 
> array[1, x, y] = array[2, x, y] = " ";  
> array is a 3D array.  
> array{1] is for text1 and array[2] for text2.  
> This statement also can be written :  
> array[1, x, y] = " ";  
> array[2, x, y] = " ";
> 
> arr = (NR == FNR ? 1 : 2);  
> The ( test ? value1 : value2 ) syntax is the equiv to:  
> if ( test )  
> return value1  
> else  
> return value2
> 
> yy[arr] -= 1  
> a short cut for  
> yy[arr] = y[arr] - 1
> 
> Jean-Pierre.

Thanks Jean for your compreshensive explanation...

I am a beginner in awk so i have a have a couple of questions so as to help me understand the logic and flow of this script more.. 😛 .Thanks

array[1, x, y] = array[2, x, y] = " ";  
array is a 3D array.  
array{1] is for text1 and array[2] for text2.  
This statement also can be written :  
array[1, x, y] = " ";  
array[2, x, y] = " ";  
Why did you equate the 2 arrays to space which is " " ?

array[arr, x, y] =$x  
What is the purpose of this statement ?

FNR \> 5 {  
next;  
What is the logic or flow behind this statement ?

$0 = $0 " ";  
What is the purpose of this statement ?

---

<div class="post-metadata">

**Author:** ![Raynon](https://community.unix.com/letter_avatar/raynon/32/5_5575768a8748004e209b776fc1b2916d.png) [@Raynon](https://community.unix.com/u/Raynon)\
**Post date:** [September 21, 2006, 10:20pm UTC](https://community.unix.com/t/2d-array-using-awk-pls-help/165386/9 "2006-09-21T22:20:10Z")

</div>

> [@ghostdog74](#):
>
> Here's an alternative in Python:
> 
> file1 :
> 
> 05 \*  
> 04 \* \* \*  
> 03 \*\* \* \* \*  
> 02 \* \* \*  
> 01 \*  
> 0 0 0 0 0  
> 1 2 3 4 5
> 
> file2:
> 
> 05 &  
> 04 \* \* \*  
> 03 \*\* \* \* \*  
> 02 # \* $  
> 01 \*  
> 0 0 0 0 0  
> 1 2 3 4 5
> 
> ```plaintext
> text1 = open("file1.txt").readlines()
> text2 = open("file2.txt").readlines()
> for y in range(len(text1)): ## y-coordinates
> if text1[y] != text2[y]:
> t1_splitted = text1[y].split()
> t2_splitted = text2[y].split()		
> for x in range(5): ## x-coordinates
> try:
> if t1_splitted[x] != t2_splitted[x]:					 
> coordinates = y,x #get coordinates
> print "Coordinates" , coordinates
> print "Symbol at text 1 %s" % t1_splitted[x] 
> print "Symbol at text 2 %s\n" % t2_splitted[x]
> print "-" * 50
> except:pass
> 
> ```
> 
> Output:
> 
> ```plaintext
> /home> python test.py
> Coordinates (0, 1)
> Symbol at text 1 *
> Symbol at text 2 &
> 
> --------------------------------------------------
> Coordinates (3, 1)
> Symbol at text 1 *
> Symbol at text 2 #
> 
> --------------------------------------------------
> Coordinates (3, 3)
> Symbol at text 1 *
> Symbol at text 2 $
> 
> --------------------------------------------------
> 
> ```

Thanks alot ,ghost for the extra info on python!! 😉
