2014-01-19 4 views
1

У меня есть файл, содержащий строки в следующем формате:более одного состояния в AWK

<firstname> <lastname> <day_of_birth> <month_of_birth> <year_of_birth> 

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

Мне удалось написать сценарий, но только если проверить день == текущий день.

Как я могу написать строку с awk, где я проверю, $ 3 == day, также проверяя, 4 $ = месяц и $ 5 == год? Спасибо

# get current date: day, month, year 
day="$(date +'%d')" 
month="$(date +'%m')" 
year="$(date +'%Y')" 

birthdays=$(awk "\$3~/$day/ {print \$1, \$2;}" users.lst) 
echo $birthdays 

ответ

3

Вы можете получить ток даты от в пределахawk следующим образом:

awk 'BEGIN { 
    "date +%d" | getline day 
    "date +%m" | getline month 
    "date +%Y" | getline year   
} 
$3==day && $4==month && $5==year { 
    print $1,$2 
}' users.lst 
+3

Если вы планируете использовать GetLine , убедитесь, что вы готовы и полностью понимаете все предостережения, описанные в http://awk.info/?tip/getline. Лично я бы не использовал getline для этого, кроме YMMV. –

+0

@EdMorton Спасибо за комментарий. На странице http://awk.info/?tip/getline сказано: 'getline - это подходящее решение для чтения из трубы. Однако, интересно, вы видите проблемы здесь? Например, если трубы должны быть закрыты перед доступом к переменным «день», «месяц» и «год». Или мы можем полагаться на то, что они имеют четко определенное значение, даже если труба не закрыта? –

+1

getline - подходящее решение для чтения для трубы, но в этом случае нет причин для чтения из трубы, в отличие от, скажем, когда вы читаете данные из файла с помощью awk и считаете полезным вызвать команду оболочки для работы по этим данным, а затем используйте getline для чтения результата, а затем продолжите обработку в awk. Да, трубы всегда должны быть закрыты, как только вы закончите с каждым из них (например, 'cmd =" ​​date +% d "; cmd | getline day; close (cmd)'), я не уверен, какие последствия не делают этого в этом случае - я просто делаю это, поэтому мне не нужно читать о том, почему. –

4

Вы не можете просто переложить переменные в awk следующим образом. Это может создать множество проблем. Вам нужно передать переменные оболочки в awk, используя опцию -v awk_var=$shell_var.

Вы можете использовать эту команду AWK:

awk -v d=$day -v m=$month -v y=$year '$3==d && $4==m && $5==y {print $1, $2}' users.lst 

Однако обратите внимание на GNU awk has built-in date/time functions и вы можете просто не вызывать команду дата 3 раза до AWK, как это:

awk '$3==strftime("%d") && $4==strftime("%m") && $5==strftime("%Y") 
    {print $1, $2}' users.lst 
4

Вы не размещать вход образца таким образом, что это предположение, но это, вероятно, что вы хотите:

awk -v date=$(date "+%d/%m/%Y") '$3"/"$4"/"$5 == date {print $1, $2}' file 
1

Вот альтернативный способ:

awk '$3=="'$(date +%d)'"&&$4=="'$(date +%m)'"&&$5=="'$(date +%Y)'"{print $1,$2}' users.lst 
Смежные вопросы