2016-06-25 5 views
1

Я пытаюсь сортировать 2 массивов с помощью следующего кода:AWK 3.1.7 - множественные петли в один для

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

Мне нужно сортировать их, предпочтительнее вместе. Я знаю, что я могу сделать, каждый в отдельности со следующим:

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

, но когда я пытаюсь следующее:

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

Я получаю следующее сообщение об ошибке:

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 

Любые и вся помощь будут оценены.

+0

Не уверен, что я понял вопрос. Для сортировки достаточно вызова асорти. Цикл должен отображать или использовать контент. Если вы хотите объединить оба массива, вы можете использовать только один индекс (свободный p2) и быть осторожным, чтобы один индекс мог быть меньше другого. –

+0

@callmeSteve, так как будет записан цикл 'for'? должен ли я использовать то же самое, что и для «асорти»? например. 'n = asorti (pacben, pacsor) n = asorti (pacben2, pacsor2) для (p = 1; p <= n; p ++)' – glly

ответ

2

В C, вы бы изменить:

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

в:

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

Это один из стандарта использует для оператора запятая. Однако оказывается, что awk не принимает оператор запятой.

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 
$ 

Спецификация POSIX для awk не включает в себя оператор запятой в списке операторов.

Вы можете использовать:

$ 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 
$ 

Это использует тот факт, что p1 и p2 инициализируются к тому же значению, и что обеим p1 и p2 отличны от нуля в инкременте части петли.

+0

Удивительная благодарность, которая работает как шарм. никогда бы не подумал, что вы можете сделать это в 'for'. – glly

+0

Повесьте - вы бы никогда не записали последний цикл, поскольку он эквивалентен гораздо более простому для for (p = 1; p <= n && p <= m; p ++) print p, p'. См. Http://stackoverflow.com/a/38038530/1745001. –

+0

Да, @EdMorton; не было бы необходимости в двух машинах управления контуром, как написано. Я предполагаю, что в теле реального цикла есть что-то, что обрабатывает (увеличивает или уменьшает так готовую, иначе настраивает) индексы цикла отдельно. –

3

Держите его простым. Там в различные возможные решения в зависимости от то, что вы действительно хотите и что blah может делать, но на основе вы принимать @JonathanLeffer's answer, это должно быть то, что вы хотите:

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

но также рассмотреть вопрос о том, как работать с массивами разных размеров:

$ 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 
+1

Ах, это приятно знать. – glly