2016-09-17 3 views
-3

У меня есть файл с несколькими строками и с каждой строкой, содержащей следующие данных-Нахождение макс значение определенной даты AWK

name 20150801|1 20150802|4 20150803|6 20150804|7 20150805|7 20150806|8 20150807|11532 20150808|12399 2015089|12619 20150810|12773 20150811|14182 20150812|27856 20150813|81789 20150814|41168 20150815|28982 20150816|24500 20150817|22534 20150818|3 20150819|4 20150820|47773 20150821|33168 20150822|53541 20150823|46371 20150824|34664 20150825|32249 20150826|29181 20150827|38550 20150828|28843 20150829|3 20150830|23543 20150831|6 

name2 20150801|1 20150802|4 20150803|6 20150804|7 20150805|7 20150806|8 20150807|11532 20150808|12399 2015089|12619 20150810|12773 20150811|14182 20150812|27856 20150813|81789 20150814|41168 20150815|28982 20150816|24500 20150817|22534 20150818|3 20150819|4 20150820|47773 20150821|33168 20150822|53541 20150823|46371 20150824|34664 20150825|32249 20150826|29181 20150827|38550 20150828|28843 20150829|3 20150830|23543 20150831|6 

трубы разделены значение указывает значение для каждого из дат в месяц. Каждая строка имеет тот же формат с одинаковым количеством столбцов. Первое имя столбца указывает уникальное имя для строки, например. 20150818 is yyyyddmm

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

+0

использование SQLite, если вы можете – perreal

+0

сообщение по крайней мере, 2 строки данных для сравнения стоимости на указанную дату. –

+0

имя первого столбца указывает уникальное имя строки. 20150818 - yyyyddmm – joe

ответ

1

Я думаю, что вы имеете в виду это:

awk -v date=20150823 '{for(f=2;f<=NF;f++){split($f,a,"|");if(a[1]==date&&a[2]>max){max=a[2];name=$1}}}END{print name,max}' YourFile 

Итак, вы передаете дату вы ищете в качестве переменной называется date. Затем вы перебираете все поля в строке и разделяете дату и значение каждого в массив с использованием | в качестве разделителя. a[1] имеет дату, a[2] имеет значение. Если совпадение даты и значение больше любого ранее увиденного максимума, сохраните это как новый максимум и сохраните первое поле из этой строки для печати в конце.

0

Как быстро & грязного раствора, мы можем выполнить это в следующих Unix команды:

yourdatafile=<yourdatafile> 
yourdate=<yourdate> 

cat $yourdatafile | sed 's/|/_/g' | awk -F "${yourdate}_" '{print $1" "$2}' | sed 's/[0-9]*_[0-9]*//g' | awk '{print $1" "$2}' |sort -k 2n | tail -n 1 

С следующими данными выборки:

$ cat $yourdatafile 
Alice 20150801|44 20150802|21 20150803|7 20150804|76 20150805|71 
Bob 20150801|31 20150802|5 20150803|21 20150804|133 20150805|71 

и yourdate=20150803 мы получаем:

$ cat $yourdatafile | sed 's/|/_/g' | awk -F "${yourdate}_" '{print $1" "$2}' | sed 's/[0-9]*_[0-9]*//g' | awk '{print $1" "$2}' |sort -k 2n | tail -n 1 
Bob 21 

и за yourdate=20150802 получаем:

$ cat $yourdatafile | sed 's/|/_/g' | awk -F "${yourdate}_" '{print $2" "$1}' | sed 's/[0-9]*_[0-9]*//g' | awk '{print $2" "$1}' | sort -k 2n | tail -n 1 
Alice 21 

Недостаток состоит в том, что только одна строка печатается наибольшее значение в день было достигнуто более чем одним именем, можно увидеть:

$ yourdate=20150805; cat $yourdatafile | sed 's/|/_/g' | awk -F "${yourdate}_" '{print $2" "$1}' | sed 's/[0-9]*_[0-9]*//g' | awk '{print $2" "$1}' | sort -k 2n | tail -n 1 
Bob 71 

Я надеюсь, что помогает в любом случае.

1

Вы не могли занять 5 секунд, чтобы дать свой образец ввода разные значения? Во всяком случае, это может работать при запуске на входе, что на самом деле имеет различные значения для даты:

$ cat tst.awk 
BEGIN { FS="[|[:space:]]+" } 
FNR==1 { 
    for (i=2;i<=NF;i+=2) { 
     if ($i==tgt) { 
      f = i+1 
     } 
    } 
    max = $f 
} 
$f >= max { max=$f; name=$1 } 
END { print name } 

$ awk -v tgt=20150801 -f tst.awk file 
name2 
Смежные вопросы