AWK: там некоторый флаг должен проигнорировать комментарии?

Строки комментария считаются в НОМЕРЕ.

  1. Там некоторый флаг должен проигнорировать комментарии?
  2. Как можно ограничить диапазон в AWK, не как передача по каналу | sed -e '1d', проигнорировать строки комментария?

Пример

$ awk '{sum+=$3} END {avg=sum/NR} END {print avg}' coriolis_data
0.885491                          // WRONG divided by 11, should be by 10
$ cat coriolis_data 
#d-err-t-err-d2-err
.105    0.005   0.9766  0.0001  0.595   0.005
.095    0.005   0.9963  0.0001  0.595   0.005
.115    0.005   0.9687  0.0001  0.595   0.005
.105    0.005   0.9693  0.0001  0.595   0.005
.095    0.005   0.9798  0.0001  0.595   0.005
.105    0.005   0.9798  0.0001  0.595   0.005
.095    0.005   0.9711  0.0001  0.595   0.005
.110    0.005   0.9640  0.0001  0.595   0.005
.105    0.005   0.9704  0.0001  0.595   0.005
.090    0.005   0.9644  0.0001  0.595   0.005
5
задан hhh 21 April 2010 в 22:33
поделиться

6 ответов

Просто уменьшите NR самостоятельно в строках комментариев:

 awk '/^[[:space:]]*#/ { NR-- } {sum+=$3} END { ... }' coriolis_data

Хорошо, это действительно ответ на вопрос, который вы задали, но вопрос, который вы действительно имели в виду:

 awk '{ if ($0 ~ /^[[:space:]]*#/) {NR--} else {sum+=$3} END { ... }' coriolis_data

(Более неудобно использовать шаблоны вне блоков, как в первом ответьте, но для этого вам придется написать шаблон комментария дважды.)

Изменить: Уилл предлагает в комментариях, используя /.../ {NR--; next} , чтобы избежать блока if-else. Я считаю, что это выглядит чище, когда у вас есть более сложные действия для совпадающих записей, но не имеет большого значения для чего-то такого простого. Возьми свою любимую!

6
ответ дан 18 December 2019 в 09:05
поделиться

лучше не трогать NR , используйте другую переменную для подсчета строк. Эта версия пропускает комментарии, а также пустые строки.

$ awk '!/^[ \t]*#/&&NF{sum+=$3;++d}END{ave=sum/d;print ave}' file
0.97404
6
ответ дан 18 December 2019 в 09:05
поделиться

Файл, который вы предоставляете для анализа AWK, не является исходным файлом, это данные , поэтому AWK ничего не знает о его конфигурации . Другими словами, для AWK в строках, начинающихся с символа #, нет ничего особенного.

При этом, конечно, вы можете пропустить комментарии, но вам нужно будет создать для этого логику: просто скажите AWK игнорировать все, что идет после "#", и посчитайте количество строк.

awk 'BEGIN {lines=0} {if(substr($1, 0, 1) != "#") {sum+=$3; lines++} } END {avg=sum/lines} END {print avg}' coriolis_data

Вы, конечно, можете сделать отступ для удобства чтения.

2
ответ дан 18 December 2019 в 09:05
поделиться

Я бы сначала удалил их с помощью sed, а затем удалите пустые строки с помощью grep.

sed 's /#.*//'

0
ответ дан 18 December 2019 в 09:05
поделиться

Есть более простой способ сделать это!

$ awk '!/#/ {print $0}' coriolis_data
.105 0.005 0.9766 0.0001 0.595 0.005
.095 0.005 0.9963 0.0001 0.595 0.005
.115 0.005 0.9687 0.0001 0.595 0.005
.105 0.005 0.9693 0.0001 0.595 0.005
.095 0.005 0.9798 0.0001 0.595 0.005
.105 0.005 0.9798 0.0001 0.595 0.005
.095 0.005 0.9711 0.0001 0.595 0.005
.110 0.005 0.9640 0.0001 0.595 0.005
.105 0.005 0.9704 0.0001 0.595 0.005
.090 0.005 0.9644 0.0001 0.595 0.005

Исправление: нет, это не так!

$ awk '!/#/ {sum+=$3}END{ave=sum/NR}END{print ave}' coriolis_data 
0.885491    // WRONG.
$ awk '{if ($0 ~ /^[[:space:]]*#/){NR--}else{sum+=$3}}END{ave=sum/NR}END{print ave}' coriolis_data
0.97404     // RIGHT.
1
ответ дан 18 December 2019 в 09:05
поделиться

Другой подход заключается в использовании условного оператора...

awk '{ if( $1 != "#" ){ print $0 } }' coriolis_data

Это означает, что awk должен пропустить строки, первой записью которых является #. Конечно, это требует, чтобы символ комментария # стоял отдельно в начале комментария.

3
ответ дан 18 December 2019 в 09:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: