拉出与日期相关的线

拉出与日期相关的线

我有一个由第一个字段编辑的文本文件sort,即月/日(例如:02-20)

我一直grep在文本文件上使用,但使用date脚本中的命令来处理今天的日期是最简单的。

我想提取前 3 天、今天的日期和未来 5 天的数据...但我不知道处理月底/下个月的简单方法。我想,我可以将其硬编码进去吗?但我一直在寻找解决问题的优雅方法,所以我正在寻求建议。

我更喜欢使用常规命令,以便脚本尽可能可移植。

即:通过便携式,我的意思不仅限于 Linux/GNU 机器(和/或必须安装特定的实用程序才能使一切运行)。目前我认为我使用的是 BSD 机器,并且我已经使用过大多数 UNIX 风格(Solaris,等等,等等,等等)——并且可能将来也会如此。

我会采用一些更复杂的程序/脚本,使用非常基本的工具,而不是每次我可能使用不同风格的 UNIX 时都必须记住安装软件包(当我可以在我的脚本目录中进行 scp 并让它工作时) )。


仅供参考:当前的date-d 标志设置夏令时:)

 -d dst  Set the system's value for Daylight Saving Time.

好的,我只是给出了一个文件中数据类型的示例(按要求)(它要大得多,obvs),但我没有给出边缘情况。这是一个边缘情况,即:如何处理月末期间,而无需在月末测试中针对每个月(或 4 种类型的月份:30、31、28 和 29)进行编程。

01-01   Something To Do Here    Notes that may run for a really long time
02-05   On the 5th of the Month         Do this other thing, because of X
02-06   The day after           Do this cleanup stuff
03-15   The Ides                Remember, remember the Brutus of December
03-29   Edge                    Does this show up on the 1st of April?
03-30   Edge2                   Does this show up on the 1st and 2nd?
03-31   Last day in the month   Shows?
04-01   Edge                    Does this show on 31st?  Or does it only show 03-35?

答案1

GNU date 允许您为选项提供字符串,-d例如-2 days5 days。该-f选项允许从文件或管道读取这些字符串。所以使用 GNUdatebash

printf '%d days\n' {-2..5} | date -f - +%m-%d | grep -f - in_file

更新

如果tcl可以接受,这里有一个打印日期的脚本:

#!/usr/bin/tclsh

set now [clock seconds]

for {set n -2} {$n<=5} {incr n} {
  set out_date [clock add $now $n days]
  puts [clock format $out_date -format %m-%d]
}

只需将其输出通过管道传递到grep -f -上面即可。

答案2

好吧,这里有一个衬里似乎可以完成这项工作......

dt=$(date +%m-%d);for i in {-2..5}; do grep "$(echo "$dt"|awk -F"-" -v count=$i '{print $1"-0"$2+count}')" mtest; done

您可以通过将其添加到 .bashrc 中来使其成为一个函数...

todolist(){  dt=$(date +%m-%d);for i in {-2..5}; do grep "$(echo "$dt"|awk -F"-" -v count=$i '{print $1"-0"$2+count}')" $1; done; }

然后你就可以称之为

todolist whateverthefilename.txt

它不是很漂亮,但我用你的数据测试了它确实有效。

$ echo -e "01-01   Something To Do Here    Notes that may run for a really long time\n02-05   On the 5th of the Month         Do this other thing,\nbecause of X\n02-06   The day after           Do this cleanup stuff\n03-15   The Ides                Remember, remember the Brutus of December">> mtest

$ dt=02-05; for i in {-2..5}; do grep "$(echo "$dt"|awk -F"-" -v count=$i '{print $1"-0"$2+count}')" mtest; done
02-05   On the 5th of the Month         Do this other thing,
02-06   The day after           Do this cleanup stuff

答案3

您可以使用touchPOSIXLY 测试日期字符串的有效性。

我将在这里使用几个选项。

  • -c
    • 不创建指定的文件如果它不存在。不要写任何有关此情况的诊断消息。
  • -t

    • 使用指定时间而不是当前时间。选项参数应为以下形式的十进制数:

      [[CC]YY]MMDDhhmm[.SS]
      
    • 如果时间无法表示为文件的时间戳,touch则应立即退出并显示错误状态。

    • 请注意,这些[[CC]YY]字段是可选的。

因此,例如:

testtime()
        if      command -v touch >&2
        then    touch -c ''
                eval '  touch -ct"$1" ""
                        [ "$?" = '"$? ]"
        else    { touch; } 2>&3
        fi      3>&2 2>/dev/null

我认为,处理可移植的事情是相当小心的。在 GNU 和传家宝的测试中(索拉里斯) touch,GNU 工具对于错误日期返回 1,对于良好日期返回 0,但传家宝版本分别返回 2 和 1。我相当确定旧的 Solaris 工具的行为在规范的基本原理中得到了特别引用,我发现:

  • 如果指定且文件不存在,至少有一种历史实现会touch增加退出代码。-c如果没有发生错误,本卷 POSIX.1-2008 要求退出状态为零。

当我比较我的传家宝工具的不同版本的行为时,我更加确信了。基本集合中的一个 - 其设计的行为尽可能与原始集合相似,并且在现代系统上仍然有用 - 是返回如上所述的 2 和 1 的那个。但是,当我使用/usr/heirloom/bin/posix2001/touch可执行文件时(该版本已根据需要进行了标准合规性修改),它的返回与 GNU 工具完全相同。

在任何情况下,该函数都可以处理旧的 Solaris、经过修改的 Solaris 和 GNU 行为,因为它将初始调用的结果与touch''文件操作数进行比较(这绝对不存在)反对第二次调用同一日期,并返回 0 表示良好的日期或 1 表示糟糕的日期。如果touch找不到,它会返回 127 并写入 stderr 。

使用方法如下:

testtime MMDD0000 && echo good date || echo bad date

...在哪里毫米DD是 2 位十进制字符串,表示您要测试的日期。您还可以通过这种方式检查有效时间 - 甚至可以使用.S秒字段。

答案4

我昨天发布了我的第一个答案,睡眠太少了。我回来了,准备再试一次。我没有尝试对日期进行 awk,而是认为自己太聪明了,所以我回去重新考虑了。

todolist(){ for i in {-2..5}; do grep "$(date -d "${date} +$i days" +%m-%d)" $1 ; done; };

只需将一行代码添加到 .bashrc 中,然后将文件提供给它即可。

这次我让约会做所有的工作。我拿到从这里提示。这一点将从今天开始添加任意天数,并以您的文件所需的格式输出......

date -d "${date} +$i days" +%m-%d)"

上面的函数现在应该可以工作,而无需求助于硬编码值。

相关内容