Мне назвали файл CSV test.csv
содержа эти значения:
A,table,20191229 16:41:58
B,table2,20191222 16:41:58
C,table3,20191223 16:40:58
D,table4,20191228 16:41:58
E,table5,20191227 16:41:58
F,table6,20191226 16:40:58
хочу выбрать только те строки, где день является воскресеньем, дата находится в YYYYMMDD HH:MM:SS
формат
Читать man date
, и сделайте что-то как:
while read line ; do
echo "line=$line">&2
din=$(echo "$line" | cut -d, -f3 | cut "-d " -f1)
echo "din=$din">&2
dayofweek=$(date --date=$din +%a)
echo "dow=$dayofweek">&2
if [[ "$dayofweek" = "Sun" ]] ; then
echo "$line"
fi
done <test.csv 2>/dev/null
Удалите финал 2>/dev/null
видеть отладочную информацию.
Данный
$ cat test.csv
A,table,20191229 16:41:58
B,table2,20191222 16:41:58
C,table3,20191223 16:40:58
D,table4,20191228 16:41:58
E,table5,20191227 16:41:58
F,table6,20191226 16:40:58
затем использование Miller
$ mlr --csvlite --implicit-csv-header --headerless-csv-output filter '
strftime(strptime($3,"%Y%m%d %H:%M:%S"), "%w") == "0"
' test.csv
A,table,20191229 16:41:58
B,table2,20191222 16:41:58
Этот однострочный код может дать ожидаемый результат плюс возможность расширить его за счет использования пайпа:
$ cat test.csv | (while read line; do day=$(date -d "$(echo $line|cut -d, -f3)" +%a); echo "$line,$day"; done;) | grep ',Sun$' | cut -d, -f1-3
A,table,20191229 16:41:58
B,table2,20191222 16:41:58
Основная логика
(во время чтения строки; do day=$(date -d "$(echo $line|cut -d, -f3)" +%a); echo "$line,$day"; готово;)
похож на waltinator, но вместо фильтрации внутри цикла я объединяю дни недели и разрешаю дальнейшую обработку:
$ cat test.csv | (while read line; do day=$(date -d "$(echo $line|cut -d, -f3)" +%a); echo "$line,$day"; done;)
A,table,20191229 16:41:58,Sun
B,table2,20191222 16:41:58,Sun
C,table3,20191223 16:40:58,Mon
D,table4,20191228 16:41:58,Sat
E,table5,20191227 16:41:58,Fri
F,table6,20191226 16:40:58,Thu
Теперь вы можете использовать grep
для фильтрации grep ',Sun$'
, включая разные дни grep -E ',(Sun|Sat)$'
если нужно:
$ cat test.csv | (while read line; do day=$(date -d "$(echo $line|cut -d, -f3)" +%a); echo "$line,$day"; done;) | grep -E ',(Sun|Sat)$'
A,table,20191229 16:41:58,Sun
B,table2,20191222 16:41:58,Sun
D,table4,20191228 16:41:58,Sat
Наконец,
Затем выберите только 3 исходные поля cut -d, -f1-3
(тут тоже свобода изменений):
$ cat test.csv | (while read line; do day=$(date -d "$(echo $line|cut -d, -f3)" +%a); echo "$line,$day"; done;) | grep -E ',(Sun|Sat)$' | cut -d, -f1-3
A,table,20191229 16:41:58
B,table2,20191222 16:41:58
D,table4,20191228 16:41:58
Сопоставление нескольких дней недели с Метод Сакамото.
#!/bin/bash
# 64 32 16 8 4 2 1
# 1 0 0 0 0 0 1 = 65 (Sat, Sun)
# Sat ´ | | | | | |
# Fri ---´ | | | | |
# Thu ------´ | | | |
# Wed ---------´ | | |
# Tue ------------´ | |
# Mon ---------------´ |
# Sun ------------------´
a=(0 3 2 5 0 3 5 1 4 6 2 4)
IFS=$'\n'
for b in $(<test.csv); do
((c=10#${b:(-17):4})) # year
((d=10#${b:(-13):2})) # month
((e=10#${b:(-11):2})) # day
(((1 << ((((c -= ((d < 3)))) + c / 4 - c / 100 + c / 400 + ${a[((d - 1))]} + e) % 7)) & 65)) && printf %s\\n "$b"
done
Ссылки: