【问题标题】:Extract hours from csv using bash-script使用 bash 脚本从 csv 中提取小时数
【发布时间】:2022-11-14 11:03:02
【问题描述】:

我有包含以下详细信息的 csv 文件,想根据时间获取详细信息,例如 如果小时在 10 和 18 之间,它应该打印为早上,其余行打印晚上。

time,id
2022-08-01T00:09:14+09:00,PKA990
2022-08-01T06:48:24+09:00,PKA990
2022-08-01T08:27:23+09:00,
2022-08-01T11:04:18+09:00,ABCD890
2022-08-01T11:23:22+09:00,ABCD890
2022-08-01T11:30:14+09:00,
2022-08-01T12:01:12+09:00,ABCD890
2022-08-01T15:11:59+09:00,JIKOPL8
2022-08-01T18:20:53+09:00,TUVNDGD

我期待输出像

time,id,session
2022-08-01T00:09:14+09:00,PKA990,night
2022-08-01T06:48:24+09:00,PKA990,night
2022-08-01T08:27:23+09:00,LOADING,night
2022-08-01T11:04:18+09:00,ABCD890,morning
2022-08-01T11:23:22+09:00,ABCD890,morning
2022-08-01T11:30:14+09:00,LOADING,morning
2022-08-01T12:01:12+09:00,ABCD890,morning
2022-08-01T15:11:59+09:00,JIKOPL8,morning
2022-08-01T18:20:53+09:00,TUVNDGD,night

请建议。

对不起,我已经编辑了一些行....当有空白时,它应该用“加载”填充

道歉

【问题讨论】:

  • 请更新问题以显示您尝试过的代码以及您的代码生成的(错误)输出

标签: bash date time


【解决方案1】:

bash 解决方案:

#! /bin/bash

INPUT_FILENAME="datetime.csv"
FLAG_FIRST=1
while read -r LINE; do
    if [[ ${FLAG_FIRST} -eq 1 ]]; then
        printf "%s,session,day_of_week
" "${LINE}"
        FLAG_FIRST=0
        continue
    fi
    # Ignore empty lines
    [[ -z "${LINE}" ]] && continue
    # If LINE ends with coma (assume id field is empty):
    #   put "LOADING" token at end of line
    [[ "${LINE}" =~ ,$ ]] && LINE+="LOADING"
    # LC_ALL=en_US to obtains day of week in english (I'am french)
    # Use ${LINE%%T*} to use date field without hour and timezone
    DAY_OF_WEEK=$(LC_ALL=en_US date +%A --date "${LINE%%T*}")
    # In english, day of week begins by an uppercase letter:
    #   use a coma after variable name tu put it in lowercase
    if [[ "${LINE}" =~ ^[-0-9]+T(10|11|12|13|14|15|16|17): ]]; then
        printf "%s,morning,${DAY_OF_WEEK,}
" "${LINE}"
    else
        printf "%s,night,${DAY_OF_WEEK,}
" "${LINE}"
    fi
done < <(cat "${INPUT_FILENAME}"; echo)

输出:

time,id,session,day_of_week
2022-08-01T00:09:14+09:00,PKA990,night,monday
2022-08-01T06:48:24+09:00,PKA990,night,monday
2022-08-01T08:27:23+09:00,LOADING,night,monday
2022-08-01T11:04:18+09:00,ABCD890,morning,monday
2022-08-01T11:23:22+09:00,ABCD890,morning,monday
2022-08-01T11:30:14+09:00,LOADING,morning,monday
2022-08-01T12:01:12+09:00,ABCD890,morning,monday
2022-08-01T15:11:59+09:00,JIKOPL8,morning,monday
2022-08-01T18:20:53+09:00,TUVNDGD,night,monday

【讨论】:

  • 谢谢,我已经编辑了我的问题。道歉
  • 如果为空,则在第二列中添加 LOADING 进行更新
  • 谢谢,@Arnaud Valmary 是否可以将最后一个字段添加为工作日时间?喜欢2022-08-01T00:09:14+09:00,PKA990,晚上,星期一?
  • 2022/7/31 23:09:14,“2022-08-01”的工作日是星期一。
  • 更新为星期几
【解决方案2】:

这是awk 解决方案:

#! /bin/bash

LC_ALL=en_US awk '
BEGIN {
    FS=OFS=","
}
NR == 1 {
    print $0, "session", "day_of_week"
    next
}
$2 == "" {
    $2 = "LOADING"
}
{
    date_timestamp=sprintf("%04d %02d %02d 00 00 00", substr($1, 1, 4), substr($1, 6, 2), substr($1, 9, 2))
    day_of_week=tolower(strftime("%A", mktime(date_timestamp)))
}
$1 ~ /^[-0-9]+T(10|11|12|13|14|15|16|17):/ {
    print $0, "morning", day_of_week
    next
}
{
    print $0, "night", day_of_week
}

' <"datetime.csv"

输出:

time,id,session,day_of_week
2022-08-01T00:09:14+09:00,PKA990,night,monday
2022-08-01T06:48:24+09:00,PKA990,night,monday
2022-08-01T08:27:23+09:00,LOADING,night,monday
2022-08-01T11:04:18+09:00,ABCD890,morning,monday
2022-08-01T11:23:22+09:00,ABCD890,morning,monday
2022-08-01T11:30:14+09:00,LOADING,morning,monday
2022-08-01T12:01:12+09:00,ABCD890,morning,monday
2022-08-01T15:11:59+09:00,JIKOPL8,morning,monday
2022-08-01T18:20:53+09:00,TUVNDGD,night,monday

【讨论】:

  • 如果为空,则在第二列中添加 LOADING 进行更新
  • 有可能得到dat_of_week对于“awk”解决方案? @Arnaud Valmary
  • 更新:添加星期几(英文为“LC_ALL=en_US”)并且只有时间戳的日期部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多