【问题标题】:Building a file index in Linux在 Linux 中建立文件索引
【发布时间】:2015-12-29 08:43:06
【问题描述】:

我有一个包含深度嵌套目录的文件系统。在树中任何节点的底层目录中都有一个目录,其名称是数据库中记录的guid。此文件夹包含附加到该记录的二进制文件(pdf、jpg 等)。

两个示例路径:

/g/camm/MOUNT/raid_fs0/FOO/042014/27/123.456.789/04.20.30--27.04.2014--RJ123.pdf
/g/camm/MOUNT/raid_fs1/FOO/052014/22/321.654.987/04.20.30--27.04.2014--RJ123.pdf

在上面的例子中,123.456.789321.654.987guids

我想建立一个完整文件系统的索引,以便我可以在我的数据库中创建一个查找表,以便轻松地将记录的guid 映射到其附加文件的绝对路径。

我可以很容易地生成一个直接的文件列表:

find /g/camm/MOUNT -type f > /g/camm/MOUNT/files.index

但我想将每个文件路径的输出解析为 CSV 文件,如下所示:

GUID    ABSOLUTEPATH    FILENAME
123.456.789 /g/camm/MOUNT/raid_fs0/FOO/042014/27/123.456.789/04.20.30--27.04.2014--RJ123.pdf    04.20.30--27.04.2014--RJ123.pdf
321.654.987 /g/camm/MOUNT/raid_fs1/FOO/052014/22/321.654.987/04.20.30--27.04.2014--RJ123.pdf    04.20.30--27.04.2014--RJ123.pdf

我想我需要将 find 命令的输出通过管道传输到 xargs 并再次传输到 awk 以将输出的每一行处理为 CSV 输出所需的格式......但我做不到工作……

【问题讨论】:

  • extremely slow 是什么意思?如果 find 对你来说太慢了,你可以考虑写一个程序来多线程遍历 FS 树..
  • 我已经编辑了这个问题以删除有关性能的问题...实际上我只是在寻找一个可以在运行时将find 的输出解析为所需 CSV 格式的命令。

标签: linux indexing awk grep find


【解决方案1】:

等待您长时间运行的find 完成,然后您 可以通过awk传递文件名列表:

awk -F/ '{printf "%s,%s,%s\n",$(NF-1),$0,$NF}' /g/camm/MOUNT/files.index

这将转换像

这样的行
/g/camm/MOUNT/raid_fs0/FOO/042014/27/123.456.789/04.20.30--27.04.2014--RJ123.pdf

进入

123.456.789,/g/camm/MOUNT/raid_fs0/FOO/042014/27/123.456.789/04.20.30--27.04.2014--RJ123.pdf,04.20.30--27.04.2014--RJ123.pdf

-F/ 使用“/”作为分隔符将行拆分为字段,NF 是 字段数,所以$NF 表示最后一个字段,$(NF-1) 表示 next-to-last,这似乎是您想要在第一列中的目录 的输出。我在 printf 中使用“,”来分隔输出列,如 在 csv 中很典型;您可以将其替换为任何字符,例如空格或“;”。

【讨论】:

    【解决方案2】:

    我认为没有什么比你的find 命令快得多了,但是 您可能对 locate 包感兴趣。它使用updatedb 命令(通常每晚由 cron 运行)来遍历文件系统并创建一个包含所有文件名的文件,其方式比其他命令容易搜索的方式。

    locate 命令用于读取数据库以查找匹配的目录、文件等,甚至使用 glob 通配符或正则表达式模式匹配。一旦尝试,没有它就很难活。

    例如,在我的系统上locate -S 列出了统计信息:

    Database /var/lib/mlocate/mlocate.db:
        59945 directories
        505330 files
        30401572 bytes in file names
        12809265 bytes used to store database
    

    我能做到

    locate rc-dib0700-nec.ko
    locate -r rc-.*-nec.ko
    locate '*/media/*rc-*-nec.ko*'
    

    立即找到像/usr/lib/modules/4.1.6-100.fc21.x86_64/kernel/drivers/media/rc/keymaps/rc-dib0700-nec.ko.xz 这样的文件。

    【讨论】:

    • 感谢这个通用解决方案。不确定它在我的用例中是否有用......我实际上是在 Windows 服务器上运行它(通过 msysgit)来为数据仓库中网络驱动器上的文件系统创建索引。它必须发生两次,因为它是在我们现在拥有的静态数据提取上,并且将再更新一次,然后变为永久静态。如果我可以以所需格式构建此 CSV 索引,那么我可以将其导入 SQL 服务器并在其上放置一个 WebService,以将用户下载请求映射到企业中正确的 UNC 路径...
    【解决方案3】:

    您几乎可以使用find-printf 选项做您想做的事。 困难在于 GUID。

    假设前缀与您的示例中的长度相同,我可能会这样做:

    find /g/camm/MOUNT -type f -printf "%h %p %f\n" | colrm 1 37 > /g/camm/MOUNT/files.index
    

    或者如果/的数量是恒定的

    find /g/camm/MOUNT -type f -printf "%h %p %f\n" | cut -d '/' -f 9- > /g/camm/MOUNT/files.index
    

    否则,我会使用sed

    find /g/camm/MOUNT -type f -printf "%h %p %f\n" | sed -e 's@^.*/\(.*\) @\1 @' > /g/camm/MOUNT/files.index
    

    【讨论】:

      猜你喜欢
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-21
      • 1970-01-01
      相关资源
      最近更新 更多