2016-03-19 5 views
0

У меня есть пример файла, который содержит следующее.Различные результаты в awk при использовании разных синтаксисов FS

logging.20160309.113.txt.log: 0 Rows successfully loaded. 
logging.20160309.1180.txt.log: 0 Rows successfully loaded. 
logging.20160309.1199.txt.log: 0 Rows successfully loaded. 

В настоящее время я знаком с двумя способами реализации синтаксиса разделителя полей в awk. Однако в настоящее время я получаю разные результаты.

Долгое время я использую

«FS =» синтаксис, когда мой FS более чем один символ.

«-f» флаг, когда мой FS - всего лишь один символ.

Я хотел бы понять, почему синтаксис FS = дает мне неожиданный результат, как показано ниже. Как-то 1-я запись остается позади.

$ head -3 reload_list | awk -F"\.log\:" '{ print $1 }' 
awk: warning: escape sequence `\.' treated as plain `.' 
awk: warning: escape sequence `\:' treated as plain `:' 
logging.20160309.113.txt 
logging.20160309.1180.txt 
logging.20160309.1199.txt 
$ head -3 reload_list | awk '{ FS="\.log\:" } { print $1 }' 
awk: warning: escape sequence `\.' treated as plain `.' 
awk: warning: escape sequence `\:' treated as plain `:' 
logging.20160309.113.txt.log: 
logging.20160309.1180.txt 
logging.20160309.1199.txt 

ответ

1

Причина вы получаете разные результаты, является то, что в случае, когда вы устанавливаете FS в программе AWK, это не в BEGIN блоке. Поэтому к тому моменту, когда вы его установили, первая запись уже была проанализирована в полях (используя разделитель по умолчанию).

Установка с -F

$ awk -F"\\.log:" '{ print $1 }' b.txt 
logging.20160309.113.txt 
logging.20160309.1180.txt 
logging.20160309.1199.txt 

Настройка FSпосле разбора первая запись

$ awk '{ FS= "\\.log:"} { print $1 }' b.txt 
logging.20160309.113.txt.log: 
logging.20160309.1180.txt 
logging.20160309.1199.txt 

Установка FS перед разбором каких-либо записей

$ awk 'BEGIN { FS= "\\.log:"} { print $1 }' b.txt 
logging.20160309.113.txt 
logging.20160309.1180.txt 
logging.20160309.1199.txt 

Я заметил этот соответствующий бит в руководстве awk. Если возможно, вы видели другое поведение ранее или с другой реализацией, это может объяснить, почему:

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

Однако многие реализации awk этого не делают. Вместо этого они откладывают разделение полей до фактического задания поля , используя ток значение FS! Это может быть трудно диагностировать.

+0

Принимая это как лучший ответ для предоставления справочных справок. – Ricsonc

0

-f предназначен для запуска сценария из файла. -F и FS работает так же

$ awk -F'.log' '{print $1}' logs 
logging.20160309.113.txt 
logging.20160309.1180.txt 
logging.20160309.1199.txt 

$ awk 'BEGIN{FS=".log"} {print $1}' logs 
logging.20160309.113.txt 
logging.20160309.1180.txt 
logging.20160309.1199.txt 
+1

Я знаю, что это не влияет на вывод, но, строго говоря, я думаю, что в обоих случаях это должно быть '\\. Log'. –

+0

Спасибо за это. – Ricsonc