из xyz в матрицу с помощью awk - PullRequest
2 голосов
/ 26 октября 2011

У меня есть проблема, которую мне удалось решить с помощью обходного пути, поэтому я надеюсь здесь научиться у вас более элегантным решениям; -)

Я должен проанализировать вывод программы: она записывает файл из трех столбцов x y z, как это

1 1 11  
1 2 12  
1 3 13  
1 4 14  
2 1 21  
2 2 22  
2 3 23  
2 4 24  
3 1 31  
3 2 32  
3 3 33  
3 4 34  
4 1 41  
4 2 42  
4 3 43  
4 4 44  

в такой матрице

11 12 13 14  
21 22 23 24  
31 32 33 34  
41 42 43 44  

Я решил с помощью двухстрочного скрипта bash, подобного этому

dim_matrix=$(awk 'END{print sqrt(NR)}' file_xyz) #since I know that the matrix has to be squared and there are no blank lines in the file_xyz  
awk '{printf("%s%s",$3, !(NR%'${dim_matrix}'==0) ? OFS :ORS ) }' file_xyz  

Не могли бы вы предложить мне способ выполнить то же самое только с помощью awk?

Ответы [ 3 ]

1 голос
/ 26 октября 2011

awk не делает настоящие многомерные массивы, но вы можете подделать его с помощью правильно построенной строки:

awk '
  {mx[$1 "," $2] = $3}
  END {
    size=sqrt(NR)
    for (x=1; x<=size; x++) {
      for (y=1; y<=size; y++)
          printf("%s ",mx[x "," y])
      print ""
    }
  }
' filename

Вы можете выполнить свой пример с помощью одного awk-вызова и вызова wc

awk -v "nlines=$(wc -l < filename)" '
  BEGIN {size = sqrt(nlines)}
  {printf("%s%s", $3, (NR % size == 0 ? ORS : OFS))
}' filename
1 голос
/ 27 октября 2011

Версия для чтения "не так":

awk '($0=$NF x)&&ORS=NR%4?FS:RS' infile

Параметры добавлены в соответствии с запросом OP:

awk '
  ($0 = $NF x) && ORS = NR % n ? FS : RS
  ' n="$1" infile

В приведенном выше сценарии я использую $ 1, но вы можете использоватьлюбая переменная shell .

Объяснение следующее:

$0 = $NF - установить $ 0 (всю текущую входную запись) на текущее значение последнего поля ($ NF).

ORS = NR % n ? FS : RS - используя троичный оператор:

expression ? return_this_if_true : return_this_otherwise,

установите для OutputRecordSeparator значение:

  • , когда NR% n оценивает значение true (т.е. возвращает значениеотличается от 0) установить ORS на текущее значение FS (FieldSeparator - по умолчанию выполняется пробел символов)

  • в противном случае установить значение RS (по умолчанию используется новая строка)

Символ x (унитарная переменная и, следовательно, строка NULL при использовании в конкатенации) необходим для правильной обработки вывода, когда последнее поле равно 0 (или пустая строка).Это связано с тем, что оператор присваивания в awk фактически в этом случае возвращает присвоенное значение, если $ NF равно 0, остальные логические выражения && будут игнорироваться.

1 голос
/ 26 октября 2011

Я не совсем уверен, что вы пытаетесь сделать, попробуйте это:

awk 'NR%4==0{print s " " $NF;s="";next}{s=s?s " " $NF:$NF}' file1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...