Linux - 查找每个目录中每组文件的最大修改日期
Linux - Finding the max modified date of each set of files in each directory
path/mydir
包含目录列表。这些目录的名称告诉我它们与哪个数据库相关。
每个目录里面都是一堆文件,但是文件名告诉我没有什么重要的。
我正在尝试在 linux bash 中编写一个命令来完成以下操作:
- 对于
path/mydir
中的每个目录,找到该目录中最后修改文件的最大时间戳
- 在父目录名称旁边打印上次修改文件的时间戳
- 排除任何小于 30 天的时间戳
- 使用正则表达式排除特定目录名称
- 按最早的时间戳排序
鉴于 path/mydir
中的目录结构:
database_1
table_1.file (last modified 2021-11-01)
table_2.file (last modified 2021-11-01)
table_3.file (last modified 2021-11-05)
database_2
table_1.file (last modified 2021-05-01)
table_2.file (last modified 2021-05-01)
table_3.file (last modified 2021-08-01)
database_3
table_1.file (last modified 2020-01-01)
table_2.file (last modified 2020-01-01)
table_3.file (last modified 2020-06-01)
我想输出:
database_3 2020-06-01
database_2 2021-08-01
这一半有效,但是查看父目录的修改日期而不是目录下文件的最大时间戳:
find . -maxdepth 1 -mtime +30 -type d -ls | grep -vE 'name1|name2'
我是 bash 的新手,非常感谢任何帮助和指导!
请你试试下面的方法好吗
#!/bin/bash
cd "path/mydir/"
for d in */; do
dirname=${d%/}
mdate=$(find "$d" -maxdepth 1 -type f -mtime +30 -printf "%TY-%Tm-%Td\t%TT\t%p\n" | sort -rk1,2 | head -n 1 | cut -f1)
[[ -n $mdate ]] && echo -e "$mdate\t$dirname"
done | sort -k1,1 | sed -E $'s/^([^\t]+)\t(.+)/\2 \1/'
提供示例的输出:
database_3 2020-06-01
database_2 2021-08-01
for d in */; do
遍历 path/mydir/
. 中的子目录
dirname=${d%/}
仅出于打印目的删除尾部斜杠。
printf "%TY-%Tm-%Td\t%TT\t%p\n"
前置修改日期和时间
到由制表符分隔的文件名。结果将如下所示:
2021-08-01 12:34:56 database_2/table_3.file
sort -rk1,2
按日期和时间字段降序排列输出。
head -n 1
选择具有最新时间戳的行。
cut -f1
提取具有修改日期的第一个字段。
[[ -n $mdate ]]
跳过空 mdate
.
sort -k1,1
就在 done
执行全局排序之后
子目录的输出。
sed -E ...
交换时间戳和目录名。它只是考虑
在这种情况下,目录名可能包含一个制表符。如果没有,你可以
通过切换时间戳和目录名的顺序来省略 sed
命令
在 echo
命令中并将 sort
命令更改为 sort -k2,2
.
至于提到的Exclude specific directory names using regex
,添加
您自己对 find
命令或其他命令的逻辑。
[编辑]
如果子目录中最后修改的文件早于指定日期,为了打印目录名称,请尝试:
#!/bin/bash
cd "path/mydir/"
now=$(date +%s)
for d in */; do
dirname=${d%/}
read -r secs mdate < <(find "$d" -type f -printf "%T@\t%TY-%Tm-%Td\n" | sort -nrk1,1 | head -n 1)
secs=${secs%.*}
if (( secs < now - 3600 * 24 * 30 )); then
echo -e "$secs\t$dirname $mdate"
fi
done | sort -nk1,1 | cut -f2-
now=$(date +%s)
将变量 now
赋值给当前时间
自纪元以来的秒数。
for d in */; do
遍历 path/mydir/
. 中的子目录
dirname=${d%/}
仅出于打印目的删除尾部斜杠。
-printf "%T@\t%TY-%Tm-%Td\n"
以秒为单位打印修改时间
由制表符分隔的纪元和修改日期。
结果将如下所示:
1627743600 2021-08-01
sort -nrk1,1
按修改时间降序排列输出。
head -n 1
选择具有最新时间戳的行。
read -r secs mdate < <( stuff )
将 secs
和 mdate
分配给
命令的输出顺序。
secs=${secs%.*}
删除小数部分。
- 条件
(( secs < now - 3600 * 24 * 30 ))
满足 if secs
比 now
. 早 30 天或更长时间
echo -e "$secs\t$dirname $mdate"
打印 dirname
和 mdate
为排序目的在 secs
之前。
sort -nk1,1
就在 done
执行全局排序之后
子目录的输出。
cut -f2-
删除 secs
部分。
path/mydir
包含目录列表。这些目录的名称告诉我它们与哪个数据库相关。
每个目录里面都是一堆文件,但是文件名告诉我没有什么重要的。
我正在尝试在 linux bash 中编写一个命令来完成以下操作:
- 对于
path/mydir
中的每个目录,找到该目录中最后修改文件的最大时间戳 - 在父目录名称旁边打印上次修改文件的时间戳
- 排除任何小于 30 天的时间戳
- 使用正则表达式排除特定目录名称
- 按最早的时间戳排序
鉴于 path/mydir
中的目录结构:
database_1
table_1.file (last modified 2021-11-01)
table_2.file (last modified 2021-11-01)
table_3.file (last modified 2021-11-05)
database_2
table_1.file (last modified 2021-05-01)
table_2.file (last modified 2021-05-01)
table_3.file (last modified 2021-08-01)
database_3
table_1.file (last modified 2020-01-01)
table_2.file (last modified 2020-01-01)
table_3.file (last modified 2020-06-01)
我想输出:
database_3 2020-06-01
database_2 2021-08-01
这一半有效,但是查看父目录的修改日期而不是目录下文件的最大时间戳:
find . -maxdepth 1 -mtime +30 -type d -ls | grep -vE 'name1|name2'
我是 bash 的新手,非常感谢任何帮助和指导!
请你试试下面的方法好吗
#!/bin/bash
cd "path/mydir/"
for d in */; do
dirname=${d%/}
mdate=$(find "$d" -maxdepth 1 -type f -mtime +30 -printf "%TY-%Tm-%Td\t%TT\t%p\n" | sort -rk1,2 | head -n 1 | cut -f1)
[[ -n $mdate ]] && echo -e "$mdate\t$dirname"
done | sort -k1,1 | sed -E $'s/^([^\t]+)\t(.+)/\2 \1/'
提供示例的输出:
database_3 2020-06-01
database_2 2021-08-01
for d in */; do
遍历path/mydir/
. 中的子目录
dirname=${d%/}
仅出于打印目的删除尾部斜杠。printf "%TY-%Tm-%Td\t%TT\t%p\n"
前置修改日期和时间 到由制表符分隔的文件名。结果将如下所示:
2021-08-01 12:34:56 database_2/table_3.file
sort -rk1,2
按日期和时间字段降序排列输出。head -n 1
选择具有最新时间戳的行。cut -f1
提取具有修改日期的第一个字段。[[ -n $mdate ]]
跳过空mdate
.sort -k1,1
就在done
执行全局排序之后 子目录的输出。sed -E ...
交换时间戳和目录名。它只是考虑 在这种情况下,目录名可能包含一个制表符。如果没有,你可以 通过切换时间戳和目录名的顺序来省略sed
命令 在echo
命令中并将sort
命令更改为sort -k2,2
.
至于提到的Exclude specific directory names using regex
,添加
您自己对 find
命令或其他命令的逻辑。
[编辑]
如果子目录中最后修改的文件早于指定日期,为了打印目录名称,请尝试:
#!/bin/bash
cd "path/mydir/"
now=$(date +%s)
for d in */; do
dirname=${d%/}
read -r secs mdate < <(find "$d" -type f -printf "%T@\t%TY-%Tm-%Td\n" | sort -nrk1,1 | head -n 1)
secs=${secs%.*}
if (( secs < now - 3600 * 24 * 30 )); then
echo -e "$secs\t$dirname $mdate"
fi
done | sort -nk1,1 | cut -f2-
now=$(date +%s)
将变量now
赋值给当前时间 自纪元以来的秒数。for d in */; do
遍历path/mydir/
. 中的子目录
dirname=${d%/}
仅出于打印目的删除尾部斜杠。-printf "%T@\t%TY-%Tm-%Td\n"
以秒为单位打印修改时间 由制表符分隔的纪元和修改日期。 结果将如下所示:
1627743600 2021-08-01
sort -nrk1,1
按修改时间降序排列输出。head -n 1
选择具有最新时间戳的行。read -r secs mdate < <( stuff )
将secs
和mdate
分配给 命令的输出顺序。secs=${secs%.*}
删除小数部分。- 条件
(( secs < now - 3600 * 24 * 30 ))
满足 ifsecs
比now
. 早 30 天或更长时间
echo -e "$secs\t$dirname $mdate"
打印dirname
和mdate
为排序目的在secs
之前。sort -nk1,1
就在done
执行全局排序之后 子目录的输出。cut -f2-
删除secs
部分。