我有一个名为的 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
。
答案1
鉴于
$ 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
然后使用磨坊主
$ 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
答案2
此行代码可以给出预期的结果,并可以通过管道使用进行扩展:
$ 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
主要逻辑
(while read line; do day=$(date -d "$(echo $line|cut -d, -f3)" +%a); echo "$line,$day"; done;)
类似于沃尔蒂纳托的但是,我没有在循环内进行过滤,而是连接了星期几并允许进一步处理:
$ 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
答案3
阅读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
即可查看调试输出。
答案4
使用 Sakamoto 方法匹配多个工作日。
#!/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
参考: