Скрипт awk не улавливает символ решетки "#"

Sep 11 2020

Как заставить awk игнорировать записи, начинающиеся с комментария, при сохранении всех остальных записей? Приведенный ниже сценарий awk не игнорирует записи, начинающиеся с символа решетки в этом примере тестового файла. Также пропускает numpyзапись.

Тестовый файл
# Version numbers have been retrieved from a range of machines and environments.
# Take them with a grain of salt.

# Direct dependencies
#python==3.6.0
#pip==9.0.1
#setuptools==38.2.4  # old for MarkupSafe 1.0 (28.8.0 is installed with py 3.6)
numpy==1.12.1  # 1.12.0
pandas==0.19.2
Скрипт awk
#! /usr/bin/awk -f

BEGIN { 
  regex=/^[a-zA-Z]+\S+/ 
  n=0
}

$1 ~ regex {print $1; n++};

END{
  {print "\n# \n# End proccessing of "FILENAME" \n# Original file had "NR" records\n# Current file record count is "n};
  { if(NR>=n) print "#\n# Mattached all records"};
}
Вывод (игнорировать столбцы)
|| #python==3.6.0
|| #pip==9.0.1
|| pandas==0.19.2
|| 
|| # 
|| # End proccessing of requirements.txt 
|| # Original file had 9 records
|| # Current file record count is 3
|| #
|| # Mattached all records

Ответы

2 EdMorton Sep 11 2020 at 07:49

regex=/^[a-zA-Z]+\S+/означает «сравнить $0с /^[a-zA-Z]+\S+/и сохранить результат в переменной regex» так regexбудет 1 или 0 в результате этого задания и , так как мы находимся в BEGINсекции , где нет линий были считаны и поэтому $ 0 все еще пуст, это эквивалентно regex=0.

\Sявляется расширением GNU awk, что означает, [^[:space:]]что если вы использовали GNU awk - оно также поддерживает строго типизированные константы регулярного выражения (см.https://www.gnu.org/software/gawk/manual/gawk.html#Strong-Regexp-Constants). Имея это в виду, вы можете сделать (обратите внимание на @символ):

$ seq 5 | awk 'BEGIN{re=@/3/} $0 ~ re'
3

но только в GNU awk.

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

$ seq 5 | awk 'BEGIN{re="3"} $0 ~ re'
3
1 ThomasDickey Sep 11 2020 at 05:30

Это не шаблон awk (похоже на Perl):

regex=/^[a-zA-Z]+\S+/ 

что-то вроде этого будет работать:

regex="^[a-zA-Z]+[^[:space:]]+"

Кроме того, ваш шаблон должен соответствовать $0(не $1). $0это вся линия. $1- это первое поле (воспринимайте его как первое слово в каждой строке: #в первом столбце может не быть сопоставления).

С этими двумя исправлениями ваш пример работает для меня ...