glly
glly

Reputation: 107

AWK 3.1.7 - multiple loops in a single for

I am trying to sort 2 arrays with the following code:

 n = asorti (pacben,pacsor)
 m = asorti (pacben2,pacsor2)

I need to sort them, preferable together. I know that I can do each separately with the following:

 n = asorti (pacben,pacsor)
for (p = 1;p <= n; p++) {
blah
}
 m = asorti (pacben2,pacsor2)
for (p2 =1;p2 <= m; p2++) {
blah
}

but when I try the following:

 n = asorti (pacben,pacsor)
 m = asorti (pacben2,pacsor2)
for (p = 1;p <= n;p++ && p2 = 1;p2 <= m;p2++) {
blah
}

I get the following error:

awk: cmd. line:25:                         for (p = 1;p <= n;p++ && p2 = 1;p2 <= m; p2++) {
awk: cmd. line:25:                                                        ^ syntax error
awk: cmd. line:25:                         for (p = 1;p <= n;p++ && p2 = 1;p2 <= m; p2++) {
awk: cmd. line:25:                                                                      ^ syntax error

Any and all help will be appreciated.

Upvotes: 1

Views: 107

Answers (2)

Ed Morton
Ed Morton

Reputation: 203995

Keep it simple. There's various possible solutions depending on whatever it is you really want and what blah might do but based on you accepting @JonathanLeffer's answer, this must be what you want:

n = asorti (pacben,pacsor)
m = asorti (pacben2,pacsor2)
for (p = 1;p <= n && p <=m; p++) {
    blah
}

but also consider how to handle arrays of different sizes:

$ cat tst.awk
BEGIN{
    n = split("A C E",a)
    m = split("B D F G H",b)
    for (p=1;p<=n && p<=m;p++) {
        print a[p] ORS b[p]
    }
    for (;p <= (n > m ? n : m);p++) {
        print (n > m ? a[p] : b[p])
    }
}

$ awk -f tst.awk
A
B
C
D
E
F
G
H

Upvotes: 3

Jonathan Leffler
Jonathan Leffler

Reputation: 754520

In C, you'd modify:

for (p = 1;p <= n;p++ && p2 = 1;p2 <= m;p2++) {

into:

for (p = 1, p2 = 1; p <= n && p2 <= m; p1++, p2++) {

This is one of the standard uses for the comma operator. However, it appears that awk does not accept the comma operator.

Mac OS X (BSD) awk:

$ awk -v n=2 -v m=3 'BEGIN { for (p = 1, p2 = 1; p <= n && p2 <= m; p1++, p2++) print p1, p2}'
awk: syntax error at source line 1
 context is
    BEGIN { for (p = >>>  1, <<< 
awk: illegal statement at source line 1
awk: illegal statement at source line 1
$

GNU awk:

$ awk -v n=2 -v m=3 'BEGIN { for (p = 1, p2 = 1; p <= n && p2 <= m; p1++, p2++) print p1, p2}'
awk: cmd. line:1: BEGIN { for (p = 1, p2 = 1; p <= n && p2 <= m; p1++, p2++) print p1, p2}
awk: cmd. line:1:                   ^ syntax error
awk: cmd. line:1: BEGIN { for (p = 1, p2 = 1; p <= n && p2 <= m; p1++, p2++) print p1, p2}
awk: cmd. line:1:                                                    ^ syntax error
$

The POSIX specification for awk does not include a comma operator in the list of operators.

You can use:

$ awk -v n=2 -v m=3 'BEGIN { for (p1 = p2 = 1; p1 <= n && p2 <= m; p1++ && p2++) print p1, p2}'
1 1
2 2
$

This exploits the fact that p1 and p2 are initialized to the same value, and that both p1 and p2 are non-zero in the increment portion of the loop.

Upvotes: 2

Related Questions