форматированное чтение с использованием awk - PullRequest
1 голос
/ 17 марта 2012

Я пытаюсь прочитать в отформатированном файле с помощью awk.Содержимое выглядит следующим образом:

    1PS1     A1    1  11.197   5.497   7.783
    1PS1     A1    1  11.189   5.846   7.700
    .
    .
    .

В следующем формате c эти строки имеют следующий формат: «% 5d% 5s% 5s% 5d% 8.3f% .3f% 8.3f» где первые 5 позицийявляются целыми числами (1), следующие 5 позиций являются символами (PS1), следующие 5 позиций являются символами (A1), следующие 5 позиций являются целыми числами (1), следующие 24 позиции разделены на 3 столбца по 8 позиций с 3-мя десятичными десятичными числами.

Я просто назвал эти строки, разделенные столбцами, используя "$ 1, $ 2, $ 3".Например,

cat test.gro | awk 'BEGIN{i=0} {MolID[i]=$1; id[i]=$2; num[i]=$3; x[i]=$4; 
y[i]=$5; z[i]=$6; i++} END { ...} >test1.gro

Но у меня возникли некоторые проблемы с этим, и теперь я пытаюсь прочитать эти файлы в отформатированном виде, как описано выше.

Любая идея, как мне это сделать

Ответы [ 2 ]

2 голосов
/ 17 марта 2012

Глядя на ваш пример ввода, кажется, что строка формата на самом деле "%5d%-5s%5s%5d%8.3f%.3f%8.3f" с первым полем строки, выровненным по левому краю.Жаль, что у awk нет функции scanf(), но вы можете получить данные с помощью нескольких substr() вызовов

awk -v OFS=: '
  {
     a=substr($0,1,5)
     b=substr($0,6,5)
     c=substr($0,11,5)
     d=substr($0,16,5)
     e=substr($0,21,8)
     f=substr($0,29,8)
     g=substr($0,37,8)
     print a,b,c,d,e,f,g
   }
'

выходов

    1:PS1  :   A1:    1:  11.197:   5.497:   7.783
    1:PS1  :   A1:    1:  11.189:   5.846:   7.700

Если у вас есть GNUawk, вы можете использовать переменную FIELDWIDTHS следующим образом:

gawk -v FIELDWIDTHS="5 5 5 5 8 8 8" -v OFS=: '{print $1, $2, $3, $4, $5, $6, $7}'

также выводит

    1:PS1  :   A1:    1:  11.197:   5.497:   7.783
    1:PS1  :   A1:    1:  11.189:   5.846:   7.700
1 голос
/ 17 марта 2012

Вы никогда не говорили точно, какие поля, по вашему мнению, должны иметь какое число, поэтому я хотел бы прояснить, как awk считает, что это работает (Ваш выбор явного вызова пустого пространства в строковых полях выходного формата заставляет менянемного волнуйтесь. Вы можете иметь другое представление об этом, чем awk.).

со страницы руководства:

Строка ввода обычно состоит из полей, разделенных белымпробел, или с помощью регулярного выражения FS.Поля обозначены $ 1, $ 2, ..., а $ 0 относится ко всей строке.Если FS имеет значение null, строка ввода разбивается на одно поле на символ.

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

Вы можете проверить это с помощью чего-то вроде:

echo "1   2 3 4" | awk '{print "1:" $1 "\t2:" $2 "\t3:" $3 "\t4:" $4}'

в командной строке.


Все это предполагает, что у вас нет ошибокFS переменная, конечно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...