如何从 macOS 终端的文本文件中获取包括今天之前日期在内的所有行?
How to get all lines including dates before today from a textfile in the macOS terminal?
文本文件中有很多日期,我想 grep
或 find
今天之前的所有日期。
行就像 abc def ghi:2018-06-20 mno pqr
和其他没有日期的行。日子乱了,乱七八糟。我想接收文件的所有行 包括今天之前的日期 (未排序,就像它们在文件中一样)。
我知道的:
- 今天 =
date +%Y-%m-%d
以及如何将其保存在变量中 $A
- 获取此日期的行
grep $A file.txt
我知道如何在 for 循环中实现它以获得一周中的某几天。但是我怎样才能找到今天之前的所有日期呢?我想我确实需要像 if $A > $B do grep $B file.txt
.
这样的 比较
感谢您的帮助!
[是的,我搜索了很多但没有找到我的解决方案。]
酷。现在遍历日期(例如从今天到 6 天前)并为每个日期搜索文件:
# iterate over i = 0, 1, 2, 3, ..., 6
for i in $(seq 0 6); do
# so substract $i days from today , for eaxmple `date --date="-5 days" +%Y-%m-%d`
A=$(date --date="-$i days" +%Y-%m-%d)
grep "$A" file.txt
# or shorter grep "$(date --date="-$i days" +%Y-%m-%d)" file.txt
done
您还可以创建一个大的 grep 参数,这应该会更快:
grep "$(for i in $(seq 0 6); do echo -n "$(date --date="-$i days" +%Y-%m-%d)\|"; done | sed 's/\|$//')" file.txt
对于从今天到 7 天前的每个日期,我生成一个看起来像 %Y-%m-%d\|
的字符串,然后我需要删除最后一个 \|
和 sed 's/\|$//'
。然后我 运行 grep 看起来像 grep "2018-06-23\|2018-06-22\|2018-06-21\|<and so on...>" file.txt
。 \|
在 grep 的表达式中用作 or
。
$ today="$(date "+%s")"
$ input="/tmp/file.txt"
$ cat "${input}"
abc def ghi:2018-06-25 mno pqr
abc def ghi:2018-06-24 mno pqr
abc def ghi:2018-06-23 mno pqr
abc def ghi:2018-06-22 mno pqr
abc def ghi:2018-06-21 mno pqr
abc def ghi:2018-06-20 mno pqr
def ghi:2018-06-20 mno pqr
abc ghi:2018-06-20mno pqr abc
abc def ghi:2017-06-20 mno pqr
abc def2018-06-20 mno pqr
abc def ghi:2018-06-19 mno pqr
def ghi:2018-06-21 mno pqr
abc ghi:2018-07-20 mno pqr
abc def ghi:2018-06-20 mno pqr
abc def2018-05-20 mno pqr
1sss018-05-20 mno pqr
1sss05-20-2018 mno pqr
$ sed -n 's/.*\([[:digit:]]\{4\}-[[:digit:]]\{2\}-[[:digit:]]\{2\}\).*//p' "${input}" \
| sort -u \
| xargs -n1 date -j -f '%Y-%m-%d' '+%s' \
| xargs -n1 -I% awk 'BEGIN{if(%<'${today}'){print %}}' \
| xargs -n1 date -j -f '%s' '+%Y-%m-%d' \
| xargs -n1 -I% grep % $input \
| sort -u
abc def ghi:2017-06-20 mno pqr
abc def ghi:2018-06-19 mno pqr
abc def ghi:2018-06-20 mno pqr
abc def ghi:2018-06-21 mno pqr
abc def ghi:2018-06-22 mno pqr
abc def2018-05-20 mno pqr
abc def2018-06-20 mno pqr
abc ghi:2018-06-20mno pqr abc
def ghi:2018-06-20 mno pqr
def ghi:2018-06-21 mno pqr
$today
是自纪元以来的当前日期(以秒为单位),$input
是您要解析的文件。 sed
寻找日期(不验证它们是真实日期,例如 0000-99-99 会匹配),第一个 sort
消除重复的输入日期,第一个 xargs/date
转换所有找到的dates into seconds since the epoch, xargs/awk
输出到今天的所有日期,下一个 xargs/dates
将日期转换回 "%Y-%d-%m"
, xargs/grep
在输入文件中查找所有前面的日期, 最后一个 sort
消除了所有重复的行。
awk
是一个非常强大的脚本工具,无需借助多个进程和管道即可完成这项工作。
#!/usr/bin/awk -f
BEGIN {
today = systime()
}
/:[0-9]{4}-[0-9]{2}-[0-9]{2} / {
for(field=1;field<NF;field++) {
if (split($field,b,/\:/) > 1)
gsub(/\-/, " ", b[2])
if (mktime(b[2] " 0 0 0") > 0)
if (mktime(b[2] " 0 0 0") < today)
print [=10=]
}
}
BEGIN
块只是将变量 today
设置为当前系统时间。
/:[0-9]{4}-[0-9]{2}-[0-9]{2} /
将只处理包含日期的行,例如以冒号开头的字符串 :
for
循环遍历一行中的所有字段以像字符串一样搜索此日期。
接下来的几行只是将字符串拆分为数组以获取日期字符串,并将所有破折号 -
替换为 space。
运行 mktime()
所有这些日期都像字符串一样,与今天的比较告诉我们该行是否合格。
最终在符合条件时打印整行。
假设您知道要在哪个列中查找日期,您也可以这样做:
awk ' < "2020-09-16"' input.txt
文本文件中有很多日期,我想 grep
或 find
今天之前的所有日期。
行就像 abc def ghi:2018-06-20 mno pqr
和其他没有日期的行。日子乱了,乱七八糟。我想接收文件的所有行 包括今天之前的日期 (未排序,就像它们在文件中一样)。
我知道的:
- 今天 =
date +%Y-%m-%d
以及如何将其保存在变量中$A
- 获取此日期的行
grep $A file.txt
我知道如何在 for 循环中实现它以获得一周中的某几天。但是我怎样才能找到今天之前的所有日期呢?我想我确实需要像 if $A > $B do grep $B file.txt
.
感谢您的帮助!
[是的,我搜索了很多但没有找到我的解决方案。]
酷。现在遍历日期(例如从今天到 6 天前)并为每个日期搜索文件:
# iterate over i = 0, 1, 2, 3, ..., 6
for i in $(seq 0 6); do
# so substract $i days from today , for eaxmple `date --date="-5 days" +%Y-%m-%d`
A=$(date --date="-$i days" +%Y-%m-%d)
grep "$A" file.txt
# or shorter grep "$(date --date="-$i days" +%Y-%m-%d)" file.txt
done
您还可以创建一个大的 grep 参数,这应该会更快:
grep "$(for i in $(seq 0 6); do echo -n "$(date --date="-$i days" +%Y-%m-%d)\|"; done | sed 's/\|$//')" file.txt
对于从今天到 7 天前的每个日期,我生成一个看起来像 %Y-%m-%d\|
的字符串,然后我需要删除最后一个 \|
和 sed 's/\|$//'
。然后我 运行 grep 看起来像 grep "2018-06-23\|2018-06-22\|2018-06-21\|<and so on...>" file.txt
。 \|
在 grep 的表达式中用作 or
。
$ today="$(date "+%s")"
$ input="/tmp/file.txt"
$ cat "${input}"
abc def ghi:2018-06-25 mno pqr
abc def ghi:2018-06-24 mno pqr
abc def ghi:2018-06-23 mno pqr
abc def ghi:2018-06-22 mno pqr
abc def ghi:2018-06-21 mno pqr
abc def ghi:2018-06-20 mno pqr
def ghi:2018-06-20 mno pqr
abc ghi:2018-06-20mno pqr abc
abc def ghi:2017-06-20 mno pqr
abc def2018-06-20 mno pqr
abc def ghi:2018-06-19 mno pqr
def ghi:2018-06-21 mno pqr
abc ghi:2018-07-20 mno pqr
abc def ghi:2018-06-20 mno pqr
abc def2018-05-20 mno pqr
1sss018-05-20 mno pqr
1sss05-20-2018 mno pqr
$ sed -n 's/.*\([[:digit:]]\{4\}-[[:digit:]]\{2\}-[[:digit:]]\{2\}\).*//p' "${input}" \
| sort -u \
| xargs -n1 date -j -f '%Y-%m-%d' '+%s' \
| xargs -n1 -I% awk 'BEGIN{if(%<'${today}'){print %}}' \
| xargs -n1 date -j -f '%s' '+%Y-%m-%d' \
| xargs -n1 -I% grep % $input \
| sort -u
abc def ghi:2017-06-20 mno pqr
abc def ghi:2018-06-19 mno pqr
abc def ghi:2018-06-20 mno pqr
abc def ghi:2018-06-21 mno pqr
abc def ghi:2018-06-22 mno pqr
abc def2018-05-20 mno pqr
abc def2018-06-20 mno pqr
abc ghi:2018-06-20mno pqr abc
def ghi:2018-06-20 mno pqr
def ghi:2018-06-21 mno pqr
$today
是自纪元以来的当前日期(以秒为单位),$input
是您要解析的文件。 sed
寻找日期(不验证它们是真实日期,例如 0000-99-99 会匹配),第一个 sort
消除重复的输入日期,第一个 xargs/date
转换所有找到的dates into seconds since the epoch, xargs/awk
输出到今天的所有日期,下一个 xargs/dates
将日期转换回 "%Y-%d-%m"
, xargs/grep
在输入文件中查找所有前面的日期, 最后一个 sort
消除了所有重复的行。
awk
是一个非常强大的脚本工具,无需借助多个进程和管道即可完成这项工作。
#!/usr/bin/awk -f
BEGIN {
today = systime()
}
/:[0-9]{4}-[0-9]{2}-[0-9]{2} / {
for(field=1;field<NF;field++) {
if (split($field,b,/\:/) > 1)
gsub(/\-/, " ", b[2])
if (mktime(b[2] " 0 0 0") > 0)
if (mktime(b[2] " 0 0 0") < today)
print [=10=]
}
}
BEGIN
块只是将变量 today
设置为当前系统时间。
/:[0-9]{4}-[0-9]{2}-[0-9]{2} /
将只处理包含日期的行,例如以冒号开头的字符串 :
for
循环遍历一行中的所有字段以像字符串一样搜索此日期。
接下来的几行只是将字符串拆分为数组以获取日期字符串,并将所有破折号 -
替换为 space。
运行 mktime()
所有这些日期都像字符串一样,与今天的比较告诉我们该行是否合格。
最终在符合条件时打印整行。
假设您知道要在哪个列中查找日期,您也可以这样做:
awk ' < "2020-09-16"' input.txt