/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/year
(29-05-22_12:40
)还是month-day-year
(05-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'])