Bash 命令根据添加日期每天归档文件
Bash command to archive files daily based on date added
我有一套脚本,涉及从远程服务器下载文件然后解析它们。每天晚上,我都想为当天下载的文件创建一个存档。
一些约束是:
正在从 Windows 服务器下载到 Ubuntu 服务器。
无法删除远程服务器上的文件。
需要添加到本地目录的日期,不是文件的创建日期。
我在下载阶段有去重运行;但是,(使用 ncftp)检查涉及比较远程目录和本地目录。一种策略是每天创建一个新文件夹,将文件下载到其中,然后 tar 在午夜后的某个时候。由于新的本地文件夹是空的,因此新一天的第一个预定下载将获取远程服务器上的所有文件出现问题。
由于限制,我考虑简单地将基于 "date added" 的文件归档到中央文件夹。使用 Mac 这非常有效,因为 HFS+ 存储扩展元数据,例如创建日期和添加日期。所以我可以将 tar 命令与下面的内容结合起来:
mdls -name kMDItemFSName -name kMDItemDateAdded -raw *.xml | \
xargs -0 -I {} echo {} | \
sed 'N;s/\n/ /' | \
但是 linux 下似乎没有类似物(至少我知道的 EXT4 没有)。
我愿意接受任何形式的解决方案,以避开将文件加倍到随后的一天。最终结果应该是一个充满 tar.gz 文件的存档目录,看起来像:
files_$(date +"%Y-%m-%d").tar.gz
根据用于备份文件的方法,修改或更改的日期应反映复制的时间 - 例如,如果您使用 cp -p 备份文件,修改日期不会更改但更改的日期将反映复制时间。
您可以使用 stat
命令获取此信息:
stat <filename>
这将 return 以下内容(以及其他未显示的文件相关信息):
Access: 2016-05-28 20:35:03.153214170 -0400
Modify: 2016-05-28 20:34:59.456122913 -0400
Change: 2016-05-29 01:39:52.070336376 -0400
此输出来自我当时使用 cp -p 复制的文件,显示为 'change'。
您可以通过指定格式调用stat来获取更改时间:
stat -c '%z' <filename>
2016-05-29 01:39:56.037433640 -0400
或以大写字母 Z 表示该时间自纪元以来的秒数。您可以将其与 date 命令结合使用以仅提取日期(或使用 grep 等)
date -d "`stat -c '%z' <filename>" -I
2016-05-29
命令 find
可用于按时间范围查找文件,在这种情况下使用标志 -cmin
'changed minutes'、-mmin
'modified minutes'、或者不太可能,-amin
'accessed minutes'。获取自午夜以来的分钟数的命令序列有点难看,但它有效。
我们必须传递 "minutes since a file was last changed" 的参数(或修改,如果该标准有效)。所以首先你必须计算自午夜以来的分钟数,然后 运行 找到。
min_since_mid=$(echo $(( $(date +%s) - $(date -d "(date -I) 0" +%s) )) / 60 | bc)
展开一点:
$(date +%s)
== 从纪元到 'now' 的秒数
"(date -I) 0"
== 今天的日期,格式为 "YYYY-MM-DD 0",其中 0 表示一天中的第 0 秒
$(date -d "(date -I 0" +%s))
== 从纪元到今天午夜的秒数
- 然后我们(有效地)回显 ( $now - $midnight ) / 60 到 bc 以将结果转换为分钟。
查找调用传递自午夜以来的分钟数,前导“-”表示最多 X 分钟前。 A'+' 表示 X 分钟或更早之前。
find /path/to/base/folder -cmin -"$min_since_mid"
实际答案
最后,要在给定目录(和子目录)中创建自今天午夜以来已更改的文件的 tgz 存档,请使用以下两个命令:
min_since_mid=$(echo $(( $(date +%s) - $(date -d "(date -I) 0" +%s) )) / 60 | bc)
find /path/to/base/folder -cmin -"${min_since_mid:-0}" -print0 -exec tar czvf /path/to/new/tarball.tgz {} +
find 的 -print0 参数告诉它用空字符串分隔文件,这将防止名称中出现空格等问题。
我唯一不确定的是您应该使用更改时间 (-cmin)、修改时间 (-mmin) 还是访问时间 (-amin)。查看您的备份文件,看看哪个字段准确反映了备份的 date/time - 我认为更改了时间,但我不确定。
更新:将 -"$min_since_mid"
更改为 -"${min_since_mid:-0}" 这样,如果未设置 min_since_mid,您将不会因参数无效而出错 -你只是不会得到任何结果。如果该变量设置不正确,您还可以用 if 语句包围查找以阻止调用。
我有一套脚本,涉及从远程服务器下载文件然后解析它们。每天晚上,我都想为当天下载的文件创建一个存档。
一些约束是:
正在从 Windows 服务器下载到 Ubuntu 服务器。
无法删除远程服务器上的文件。
需要添加到本地目录的日期,不是文件的创建日期。
我在下载阶段有去重运行;但是,(使用 ncftp)检查涉及比较远程目录和本地目录。一种策略是每天创建一个新文件夹,将文件下载到其中,然后 tar 在午夜后的某个时候。由于新的本地文件夹是空的,因此新一天的第一个预定下载将获取远程服务器上的所有文件出现问题。
由于限制,我考虑简单地将基于 "date added" 的文件归档到中央文件夹。使用 Mac 这非常有效,因为 HFS+ 存储扩展元数据,例如创建日期和添加日期。所以我可以将 tar 命令与下面的内容结合起来:
mdls -name kMDItemFSName -name kMDItemDateAdded -raw *.xml | \
xargs -0 -I {} echo {} | \
sed 'N;s/\n/ /' | \
但是 linux 下似乎没有类似物(至少我知道的 EXT4 没有)。
我愿意接受任何形式的解决方案,以避开将文件加倍到随后的一天。最终结果应该是一个充满 tar.gz 文件的存档目录,看起来像:
files_$(date +"%Y-%m-%d").tar.gz
根据用于备份文件的方法,修改或更改的日期应反映复制的时间 - 例如,如果您使用 cp -p 备份文件,修改日期不会更改但更改的日期将反映复制时间。
您可以使用 stat
命令获取此信息:
stat <filename>
这将 return 以下内容(以及其他未显示的文件相关信息):
Access: 2016-05-28 20:35:03.153214170 -0400
Modify: 2016-05-28 20:34:59.456122913 -0400
Change: 2016-05-29 01:39:52.070336376 -0400
此输出来自我当时使用 cp -p 复制的文件,显示为 'change'。
您可以通过指定格式调用stat来获取更改时间:
stat -c '%z' <filename>
2016-05-29 01:39:56.037433640 -0400
或以大写字母 Z 表示该时间自纪元以来的秒数。您可以将其与 date 命令结合使用以仅提取日期(或使用 grep 等)
date -d "`stat -c '%z' <filename>" -I
2016-05-29
命令 find
可用于按时间范围查找文件,在这种情况下使用标志 -cmin
'changed minutes'、-mmin
'modified minutes'、或者不太可能,-amin
'accessed minutes'。获取自午夜以来的分钟数的命令序列有点难看,但它有效。
我们必须传递 "minutes since a file was last changed" 的参数(或修改,如果该标准有效)。所以首先你必须计算自午夜以来的分钟数,然后 运行 找到。
min_since_mid=$(echo $(( $(date +%s) - $(date -d "(date -I) 0" +%s) )) / 60 | bc)
展开一点:
$(date +%s)
== 从纪元到 'now' 的秒数
"(date -I) 0"
== 今天的日期,格式为 "YYYY-MM-DD 0",其中 0 表示一天中的第 0 秒$(date -d "(date -I 0" +%s))
== 从纪元到今天午夜的秒数- 然后我们(有效地)回显 ( $now - $midnight ) / 60 到 bc 以将结果转换为分钟。
查找调用传递自午夜以来的分钟数,前导“-”表示最多 X 分钟前。 A'+' 表示 X 分钟或更早之前。
find /path/to/base/folder -cmin -"$min_since_mid"
实际答案
最后,要在给定目录(和子目录)中创建自今天午夜以来已更改的文件的 tgz 存档,请使用以下两个命令:
min_since_mid=$(echo $(( $(date +%s) - $(date -d "(date -I) 0" +%s) )) / 60 | bc)
find /path/to/base/folder -cmin -"${min_since_mid:-0}" -print0 -exec tar czvf /path/to/new/tarball.tgz {} +
find 的 -print0 参数告诉它用空字符串分隔文件,这将防止名称中出现空格等问题。
我唯一不确定的是您应该使用更改时间 (-cmin)、修改时间 (-mmin) 还是访问时间 (-amin)。查看您的备份文件,看看哪个字段准确反映了备份的 date/time - 我认为更改了时间,但我不确定。
更新:将 -"$min_since_mid"
更改为 -"${min_since_mid:-0}" 这样,如果未设置 min_since_mid,您将不会因参数无效而出错 -你只是不会得到任何结果。如果该变量设置不正确,您还可以用 if 语句包围查找以阻止调用。