Используйте awk для анализа файла csv - в сочетании с командой оболочки date в awk - PullRequest
1 голос
/ 26 апреля 2019

У меня есть файл .csv, в котором есть даты и ответ о том, приятен он или нет:

2019-04-1,enjoyable
2019-04-2,unenjoyable
2019-04-3,unenjoyable
2019-04-4,enjoyable
2019-04-5,unenjoyable
2019-04-6,unenjoyable
2019-04-7,enjoyable
2019-04-8,unenjoyable
2019-04-9,unenjoyable
2019-04-10,enjoyable
2019-04-11,enjoyable
2019-04-12,enjoyable
2019-04-13,unenjoyable
2019-04-14,enjoyable
2019-04-15,unenjoyable
2019-04-16,unenjoyable
2019-04-17,unenjoyable
2019-04-18,enjoyable
2019-04-19,unenjoyable
2019-04-20,unenjoyable
2019-04-21,unenjoyable
2019-04-22,unenjoyable
2019-04-23,unenjoyable
2019-04-24,unenjoyable
2019-04-25,unenjoyable
2019-04-26,unenjoyable

Что я хочу сделать, это напечатать день недели в третьем столбце, разделив его символом ',' следующим образом:

2019-04-1,enjoyable,2
2019-04-2,unenjoyable,3

Я пытался:

dates=$(awk '{FS=","}{print $1,$2}' weather_stat.csv')

weeks=$(
for vars in $dates[first_row]
do
echo $(date -j -f '%Y-%m-%d' $vars "+%w")
done
)

merge($dates,$weeks)

Первая часть кода работает без каких-либо проблем, но во второй части я запутался в том, как получить данные в первой строке (поэтому я использую даты [first_row] для обозначения первой строки в переменной даты) из переменной «даты», чтобы мы могли применить к ней метод «дата»

И в третьей части я хочу объединить эти две таблицы. Я обнаружил функцию 'join', но, похоже, она работает с двумя файлами вместо двух переменных (я не хочу, чтобы во время процесса появлялись новые файлы)

Может кто-нибудь сказать мне, как получить строки в переменной вместо файла в оболочке и способ объединения двух табличных переменных?

Ответы [ 3 ]

3 голосов
/ 26 апреля 2019

Когда вы изучаете сценарии оболочки, вот код для изучения:

  1. , чтобы прочитать ваш CSV-файл и получить номер дня недели для каждой даты в файле:

    while IFS=, read -r date rest; do echo "$date,$(date -d "$date" +%w)"; done < file.csv
    
  2. , чтобы объединить вывод этой команды с вашим файлом:

    weekdays=$(while IFS=, read -r date rest; do echo "$date,$(date -d "$date" +%w)"; done < file.csv)
    join -t, file.csv <(echo "$weekdays")
    

    или без необходимости сохранять результат в промежуточной переменной

    join -t, file.csv <(
        while IFS=, read -r date rest; do echo "$date,$(date -d "$date" +%w)"; done < file.csv
    )
    

    Символы новой строки в <() не обязательны, но полезны для поддерживаемого кода.

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

3 голосов
/ 26 апреля 2019

с GNU awk:

awk' BEGIN{FS=OFS=","}
     { split($1,a,"-")
       t=sprintf("%0.4d %0.2d %0.2d 00 00 00",a[1],a[2],a[3]);
       print $0,strftime("%w",mktime(t))
     }' file.csv
1 голос
/ 26 апреля 2019

Имеется только оболочка Bourne, поэтому она менее эффективна, чем awk, если в вашем файле CSV много строк:

while IFS=, read date enjoy; do
    date -d "$date" +"$date,$enjoy,%w"
done < your.csv
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...