Shell 脚本中的正则表达式将正则表达式过滤器连接到文件名中

RegEx in Shell script concatenates RegEx filter into filename

提问人:Lars H 提问时间:10/16/2023 最后编辑:Wiktor StribiżewLars H 更新时间:10/17/2023 访问量:43

问:

我想检测名称中具有特定日期戳的文件是否在目录中。但是,还有一个连接到它的时间戳。我可以计算日期戳,但不能计算时间戳,所以我需要某种通配符。

这是示例文件名: 这是我的表达式: 但它实际上搜索这个文件名(由 echo 检查):backup_myserver_202310152100.loglog_file="backup_${hostname_arg}_${logfile_sunday}[0-9]*.log"backup_myserver_20231015[0-9]*.log

如果有帮助,时间戳始终由 for 数字表示。

我试图从 www 和这里的其他问题中获得解决方案,但似乎我不是为正则表达式而生的。

我也尝试了上面的表达式:因为我读了一点确实代表一个字符。消息来源的答案非常多样化。log_file="backup_${hostname_arg}_${logfile_sunday}{....}.log"

bash shell 逻辑 glob

评论

0赞 mandy8055 10/16/2023
正则表达式解决方案看起来更简单。这是你要找的吗?backup_myserver_20231015\d{4}\.log

答:

1赞 Murali Kadambi 10/16/2023 #1

您的命令似乎工作正常

find -maxdepth 1 -type f -name  "backup_myserver_[0-9]*.log"

我也试着把它放在一个小的 shell 脚本中,它在那里也起作用了

#!/bin/bash
expr='backup_myserver_[0-9]*.log'
result=$(find ./ -maxdepth 1 -type f -name "${expr}")
echo $result

shell 脚本的代码结果

1赞 Renaud Pacalet 10/16/2023 #2

在分配变量时,存储在变量中的是模式本身 (),而不是将其扩展到现有文件名,因为 1) 您用双引号括了它(引号之间没有进行路径名扩展)和 2) 路径名扩展永远不会在参数赋值的右侧完成。backup_myserver_20231015[0-9]*.log

验证所有这些的简单方法是键入以查看它是什么以及它有什么值。您还可以键入 which 打印模式,哪个 print 文件名(如果存在),因为未加引号,并且在执行之前执行路径名扩展。declare -p log_filelog_fileecho "$log_file"echo $log_file$log_fileecho

更好的方法是分配一个数组,其中不带引号的模式和 on 选项,这样,如果没有匹配的日志文件(输出前缀为 ):nullglob-|

shopt -s nullglob
log_file=( backup_${hostname_arg}_${logfile_sunday}[0-9]*.log )
if (( ${#log_file[@]} == 0 )); then
  printf 'no log files\n'
else
  printf '%s\n' "${log_file[@]}"
fi
-| backup_myserver_202310152100.log
-| backup_myserver_202310152101.log
...

如果您想精确匹配 4 位数字,您可以尝试:

$ log_file=( backup_${hostname_arg}_${logfile_sunday}[0-2][0-9][0-5][0-9].log )

你也可以使用 from GNU ,如果有的话,与正则表达式一起使用,而不是更简单的 glob 模式:findfindutils

find . -maxdepth 1 -regextype gnu-awk -type f -regex "\./backup_${hostname_arg}_${logfile_sunday}[0-9]{4}\.log"

评论

0赞 Lars H 10/17/2023
谢谢,就是这样。我的错误不在于正则表达式本身,而在于我使用它的方式。感谢您对我的错误处理的解释