Grep 选择以日期和时间作为文件名的文件

Grep 选择以日期和时间作为文件名的文件

/home/download/file我在Linux 上有以下文件:

Abc_05-29-2022_12:30:01
Abc_05-29-2022_12:40:01
Abc_05-29-2022_12:50:02
Abc_05-29-2022_12:45:01
Abc_05-29-2022_12:35:01
Abc_05-30-2022_12:30:01
Abc_05-30-2022_12:35:01
Abc_05-30-2022_12:40:01
Abc_05-30-2022_12:20:01
Abc_05-30-2022_12:50:01

我想使用 bash 脚本从中 grep 选定的文件,并想将这些文件复制到其他位置:

  • 源路径:/home/Download/files
  • 目的地:/home/测试

例如,我想 grep 从abc_29-05-22_12:40:0[1-2]到 的文件abc_30-05-22_12:20:0[1-2]。并使用 shell 脚本将这些文件复制到其他路径

答案1

像这样的工具grep不适合根据数字限制(日期)选择文件。正则表达式很快就会变得复杂且难以维护。在可以进行数字比较的情况下,需要一些其他脚本语言(不是 grep)。在这种情况下,find这不是正确的工具,因为它能够查看修改日期,但很难根据文件名称选择文件。

另外,您的问题中的日期格式存在一些不一致。是day/month/year29-05-22_12:40)还是month-day-year05-29-2022)?

并且,日期命令(通常)无法理解使用破折号 ( -) 而不是斜杠 ( )的格式。/

因此,进行一些调整后,该脚本应该满足您的要求:

#!/bin/bash --

dirsource="/home/Download/files"
dirdestin="/home/test"

filestart="$( date -ud '2022/05/29 12:40' +'%s' )"
fileend="$(   date -ud '2022/05/30 12:20' +'%s' )"

while IFS="" read line; do
    IFS="_-" read name month day year time <<<"$line"
    filenow="$(date -ud "$year/$month/$day $time" +"%s")"
    if [[ $filenow -ge $filestart ]] && [[ $filenow -le $fileend ]]; then
        echo \
        mv "$dirsource/$line" "$dirdestin/$line"
    fi
done <./infile

echo \当确信它会执行您想要的操作时,删除实际执行命令的行。

答案2

要复制名称代表日期从 2022-05-29T12:40:01 到 2022-05-30T12:20:02(当它们具有格式时)的文件Abc_mm-dd-yyyy_HH:MM:SS,使用 zsh(而不是 bash)glob,您可以这样做:

set -o extendedglob
cp /home/download/file/*(e['
  [[ $REPLY:t = (#b)Abc_(<1-12>-<1-31>)-(<->)_(<0-23>:<0-59>:<0-59>) &&
     ${t::=$match[2]-$match[1]T$match[2]} >= 2022-05-29T12:40:01 &&
     $t <= 2022-05-30T12:20:02 ]]']) /home/test/

我们以标准yyyy-mm-ddTHH:MM:SS格式重新排列这些时间戳,然后可以进行词法比较。

您还可以在辅助函数中进行检查,例如:

range() {
  set -o localoptions -o extendedglob
  local match t
  [[ $REPLY:t = (#b)*_(<1-12>-<1-31>)-(<->)_(<0-23>:<0-59>:<0-59>) &&
     ${t::=$match[2]-$match[1]T$match[2]} >= $1 && $t <= $2 ]]
}

进而:

cp /home/download/file/Abc*(e['range 2022-05-29T12:40:01 2022-05-30T12:20:02'])

相关内容