为什么sed返回的字符数超过了要求

时间:2019-02-07 03:02:46

标签: sed

在我的脚本的一部分中,我试图生成文件提交的年月列表。由于文件包含时间戳,因此我应该能够将文件名剪切到月份位置,然后执行sort + uniq过滤。但是sed会为其中一个文件生成异常值。

我正在使用此命令序列

  ls -1 service*json | sed -e "s|\(.*201...\).*json$|\1|g" | sort |uniq

这在大部分时间都有效,除了在某些情况下会输出整个时间戳:

$ ls
service-parent-20181119092630.json  service-parent-20181123134132.json  service-parent-20181202124532.json  service-parent-20190121091830.json  service-parent-20190125124209.json
service-parent-20181119101003.json  service-parent-20181126104300.json  service-parent-20181211095939.json  service-parent-20190121092453.json  service-parent-20190128163539.json
service-parent-20181120095850.json  service-parent-20181127083441.json  service-parent-20190107035508.json  service-parent-20190122093608.json
service-parent-20181120104838.json  service-parent-20181129155835.json  service-parent-20190107042234.json  service-parent-20190122115053.json

$ ls -1 service*json | sed -e "s|\(.*201...\).*json$|\1|g" | sort |uniq
service-parent-201811
service-parent-201811201048
service-parent-201812
service-parent-201901

我也尝试过这种变体,但第二行输出仍然返回:

  ls -1 service*json | sed -e "s|\(.*201.\{3\}\).*json$|\1|g" | sort |uniq

有人可以解释为什么在请求的3个字符之后返回service-parent-201811201048吗?

谢谢。

3 个答案:

答案 0 :(得分:0)

service-parent-201811201048恰好有201048201...匹配。

可以尝试ls -1 service*json | sed -e "s|\(.*-201...\).*json$|\1|g" | sort |uniq-前面加一个破折号201...

答案 1 :(得分:0)

不建议解析ls的输出。请尝试:

for i in service*json; do
    sed -e "s|^\(service-.*-201[0-9]\{3\}\).*json$|\1|g" <<< "$i"
done | sort | uniq

答案 2 :(得分:0)

您的问题已在https://stackoverflow.com/a/54565973/1745001进行了解释(即.*贪婪),请尝试以下操作:

$ ls | sed -E 's/(-[0-9]{6}).*/\1/' | sort -u
service-parent-201811
service-parent-201812
service-parent-201901

以上要求使用通过-E支持ERE的sed,例如GNU sed和OSX / BSD sed。