在Unix系统中使用Shell脚本从文件名中提取日期

10

我正在处理shell脚本。我想从文件名中提取日期。

文件名为:abcd_2014-05-20.tar.gz

我希望从中提取日期:2014-05-20

6个回答

23
echo abcd_2014-05-20.tar.gz |grep -Eo '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}'      

输出:

2014-05-20

grep 可以接受从 echo 标准输入中获取的内容,或者如果你将这些字符串存储在文件中,也可以使用 cat 命令。

-E 将 PATTERN 解释为扩展正则表达式。

-o 仅显示与 PATTERN 匹配的那一部分。

[[:digit:]] 它只会从输入中提取数字。

{N} 它将检查给定字符串中 N 个数字,例如:4 表示年份,2 表示月份和日期。

最重要的是,它可以在不使用任何分隔符(如“_”和“.”)的情况下提取信息。这就是为什么它是最灵活的解决方案。


我有一些想法,但后来发现不需要了,所以我把它删掉了。@AvinashRaj - Arnab Nandy
嗨,谢谢。我想知道如何在shell脚本中使用它?我想将它赋值给一个变量。 - priyanka
好的..非常感谢 :) - priyanka
没有问题,我们会毫不犹豫地帮助您解决可接受的问题。 - Arnab Nandy
1
@Skynet - 对我来说,以下命令完美运行:fdate=$(echo $f | grep -Eo '[[:digit:]]{4}[[:digit:]]{2}[[:digit:]]{2}') - Mayur Gite
显示剩余6条评论

12
使用自定义字段分隔符来使用awk非常简单:
echo 'abcd_2014-05-20.tar.gz' | awk -F '[_.]' '{print $2}'
2014-05-20

1
我喜欢它。非常简单,学到了-F甚至可以用来提取两个分隔符之间的字符串。 - SMA

7

Use grep:

$ ls -1 abcd_2014-05-20.tar.gz | grep -oP '[\d]+-[\d]+-[\d]+'
2014-05-20
  • -o选项使grep仅打印匹配的部分。
  • -P选项将模式解释为Perl正则表达式。
  • [\d]+-[\d]+-[\d]+:表示一个或多个数字后面跟随一个破折号(3次),可以匹配您的日期。

不需要在字符类中加入\d,只需使用grep -oP '\d+-\d+-\d+'即可。为了更准确,可以使用grep -oP '\d{4}-\d{2}-\d{2}'。有些grep不支持P,这种情况下请使用E代替P,如grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' - Avinash Raj

2

以下是更多例子:

  1. 使用 cut 命令(与 awk 命令相比,cut 命令更易读)
echo "abcd_2014-05-20.tar.gz" | cut -d "_" -f2 | cut -d "." -f1

输出结果为:

2014-05-20
  1. 使用 grep 命令
echo "abcd_2014-05-20.tar.gz" | grep -Eo "[0-9]{4}\-[0-9]{2}\-[0-9]{2}"

输出结果为:

2014年5月20日

使用grep命令格式的另一个优点是,它还可以帮助获取多个日期,例如:

echo "ab2014-15-12_cd_2014-05-20.tar.gz" | grep -Eo "[0-9]{4}\-[0-9]{2}\-[0-9]{2}"

输出结果为:

2014-15-12
2014-05-20

谢谢。我该如何将其分配给一个变量并在任何地方使用该变量? - priyanka
1
DATE=$(echo "abcd_2014-05-20.tar.gz" | cut -d "_" -f2 | cut -d "." -f1)。其他命令同理。 - Balaji Reddy

1
多种方法可以实现它:

echo abcd_2014-05-20.tar.gz | sed -n 's/.*_\(.*\).tar.gz/\1/p'

sed将提取日期并将其打印出来。

另一种方法:

filename=abcd_2014-05-20.tar.gz
temp=${filename#*_}
date=${temp%.tar.gz}

这里的temp将保存文件名中“_”后面的字符串,即2014-05-20.tar.gz。然后您可以通过删除末尾的.tar.gz来提取日期。


你不需要一个捕获组。只需使用 sed 's/^[^_]*_\|\..*//g' 即可。 - Avinash Raj

1
我将使用带有“grep”命令的某种正则表达式,具体取决于您的文件名如何创建。
如果您的日期始终在“_”字符之后,我将使用类似以下内容的表达式。
ls -l | grep ‘_[REGEXP]’

在这里,REGEXP是根据您的日期格式编写的正则表达式。

请看这里 http://www.linuxnix.com/2011/07/regular-expressions-linux-i.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接