我发现自己处于一个可怕的境地,需要将文件系统数据吸入数据库进行分析。我用来提取此数据的方法之一是使用以下 GNU find 命令行。
find . -printf '__:__%M__:__%u__:__%g__:__%s__:__%Cs__:__%p\n'
这用作__:__
理论上永远不会出现在实际文件或目录名称中的分隔符。
问题是我现在还需要合并 cksum,因为我需要文件的快速校验和。
我什么想要做的就是做类似的事情:
find . -exec cksum {} \; -printf '__:__%M__:__%u__:__%g__:__%s__:__%Cs__:__%p\n'
这使得所有这些都成为一个单行和一次通过文件系统的过程。但这会在单独的行上输出 cksum。
有没有某种方法可以组合 -exec cksum 以便它显示为我可以在 printf 中使用的值?
找到最好的工具来做到这一点吗?我应该使用其他工具吗?
谢谢你!
答案1
首先,一些注意事项:
__:__
文件路径中不会出现任何阻止或换行符,__:__
也不会出现在路径之前打印的任何字段中。mkdir -p $'__:__/\n\n\n'
如果您想检查的话请尝试。文件路径中可以出现除 0 之外的任何字节值。这些字节甚至不必组成字符,因此通常不能将文件路径视为文本,更不用说单行文本了。通常我们使用 NUL 分隔的记录来可靠地表示文件路径列表。
%u
并%g
给你A与文件的 uid/gid 对应的用户/组名。一个用户 ID 可以有多个用户名,而 uid 123 的用户名可能是今天的用户名,明天的用户名。换句话说,您获得的并不是文件固有的,而是嵌入了系统用户数据库中的信息。报告的文件的顺序
find
是不确定的。如果目标是能够检测目录层次结构中的某些内容何时发生更改,您将需要对该列表进行排序。注意
%Cs
只能给你精确到秒的精度。用于%C@
完全精确。
在这里,你可以(用zsh
或bash
)
find . -printf '%M/%U/%G/%s/%C@/%p\0' | LC_ALL=C sort -z |
while IFS=/ read -rd '' mode uid gid size ctime file; do
cksum=$(cksum < "$file") || continue
# do what to have to do with $mode $uid $gid $size $ctime $cksum $file
done
您可能还想选择比 更可靠的校验和算法cksum
。
请注意,使用 时bash
,您不能选择除/
上述之外的任何其他分隔符。例如,如果您选择:
并且有一个名为./dir/file:
(尾随:
)的文件,bash
则 会read
拆分mode:uid:gid:size:ctime:./dir/file:
为mode
, uid
, gid
, size
, ctime
,./dir/file
并且尾随:
会丢失。这是 POSIX 要求(被 zsh 忽略)。/
保证不会出现在 . 输出的文件路径末尾find
。
另请注意,该-printf
谓词特定于 的 GNU 实现find
并且不可移植。-z
而处理非文本数据的能力也是GNU的sort
扩展。