我有一些名为:
- 2016-02-10_03-52.log
- 2016-02-10_04-43.log
- 2016-02-10_02-13.log
- ...
- 2016-03-15_07-03.log
- 2016-03-15_09-08.log
基本上模式是:YYYY-MM-DD_.log
我想创建以相同模式开头的所有文件的 tar,例如:
- 2016-02-10.tar
- ...
- 2016-03-15.tar
问题是我事先不知道模式,只知道它的结构。
我不知道如何搜索以相同(未知)模式开头的文件。
非常感谢任何帮助。谢谢
根据下面的“标称动物”解决方案:
导出 LANG=C LC_ALL=C 查找 . -名称'[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*' -printf '%f\n' | sed -e 的|。$||g'|排序|优衣库 |读取 NAME 时;确实找到了。 -名称“${NAME}_" -printf '%p\n' | tar -cJf "${NAME}.xz" -T - --no-unquote 完成
答案1
这是一个非常简单的两步过程来完成此操作。
首先,用于find
生成应最终存档的所有文件的列表。用于sed
为每个生成存档名称。通过sort
和过滤输出uniq
,以确保您拥有所需的所有档案的名称。例如:
find . -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_*' -printf '%f\n' | sed -e 's|_.*$||g' | sort | uniq
请注意,我们使用%f
上面的格式仅获取文件名,而不是完整路径。
接下来,我们通过一个小的 bash 循环来读取每个存档名称,find
再次使用它来查找所有日志文件,通过管道将该列表tar
生成存档。
为了运行这样的命令,我想确保我们使用 C/POSIX 语言环境(没有本地化的错误消息或其他格式)。这是通过将环境变量设置LANG
为LC_ALL
来完成的C
。所以,我使用的整个命令序列是
export LANG=C LC_ALL=C
find . -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_*' -printf '%f\n' | sed -e 's|_.*$||g' | sort | uniq | while read NAME ; do
find . -name "${NAME}_*.log" -printf '%p\n' | tar -cJf "${NAME}.tar.xz" -T - --no-unquote
done
-J
中的参数指-cJf
的是 XZ 压缩(它又快又好,您可能确实想要这样);我喜欢读-cJf
作“创建 XZ 存档文件”。意味着-T -
每个存档中的文件都是从标准输入提供的,并且--no-unquote
意味着文件名是原始的,没有引用。
请注意,存档名称的模式非常适合此处的通配。 (也就是说,我们可以将其提供给find -name ...
。)如果模式包含*
、?
、[
或]
,我们需要转义它们。可行,但很烦人。在我看来,OP 非常好地选择了文件名模式。
答案2
鉴于tar
有一个“追加”选项(-r
),您可以保持愚蠢简单:
for file in *.log; do tar -rf "${file%%_*}.tar" "$file" ; done
您不能包含z
使用这种特定方法压缩日志的选项 ( tar: Cannot update compressed archives
),但是这很简单。
当然,根据您的需要为通配模式添加稳健性。该版本假设全部 .log
文件应该被压缩到一个或另一个存档中。