将 find 命令与其他命令连接起来

将 find 命令与其他命令连接起来

我正在尝试索引我的文件系统。我想要做的是:执行命令find,并为每个条目保存上次访问时间、上次修改时间、计算哈希值和其他操作。为了做到这一点,我想执行以下命令:

find . -printf 'PATHNAME=%p -- NAME=%f -- SIZE=%s -- LAT=%a -- LCT=%c -- LMT=%t  \n' -exec file {} \; -exec md5sum {} \;

输出类似于:

PATHNAME=./script -- NAME=script -- SIZE=807 -- LAT=Fri Apr 15 16:39:52.0874615579 2016 -- LCT=Tue Apr 12 12:20:57.0767950320 2016 -- LMT=Tue Apr 12 12:20:57.0767950320 2016 <br>
./script: ASCII text <br>
cf1b934c226b194bee96106ea3f019a4  ./script

现在我想获取所有这些参数(例如用 解析它们awk)并将它们放在某个地方(例如数据库中)。所以,我的问题是:我每次如何将这 3 行重定向到脚本进行解析?有没有更好的方法来编写命令?

答案1

我会使用类似这样的东西(没有数据库中的插入部分)

while read EMPTY_LINE; do
  read FILE_SIZE
  read FILE_AT
  read FILE_MT
  read FILE_CT
  read MIME_INFO
  read HASH FILE_PATH

  echo
  echo 'File path: '"$FILE_PATH"
  echo 'File size: '"$FILE_SIZE"
  echo 'File times (access - modified - changed): '"$FILE_AT - $FILE_MT - $FILE_CT"
  echo 'MIME stuff: '"$MIME_INFO"
  echo 'Hash: '"$HASH"
done < <(find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \; )

好的,那么这里究竟发生了什么,以及我为什么要这样做?

查找命令

find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \;首先执行命令。

让我们详细分析一下。

find ..在(当前目录)中查找内容

-type -f仅查找文件

-printf '\n'为每个文件匹配打印一个空文件

-exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \;执行 stat 命令打印几个我自己指定的文件统计信息 - 请参阅stat --help可用的统计信息

-exec file -b {} \;执行文件命令来确定 MIME 信息。-b确保文件名不会随之打印。无论如何我们都会忽略它。

-exec md5sum {} \;执行md5sum命令计算文件内容的md5哈希值。

一切顺利。-exec参数按指定的顺序处理。这意味着每个文件匹配,我们将得到以下几行:

[FILE SIZE - from stat command]
[FILE LAST ACCESS TIME - from stat command]
[FILE LAST MODIFICATION TIME - from stat command]
[FILE LAST CHANGE TIME - from stat command]
[MIME INFO - from file command]
[HASH - from md5sum command] [FILE PATH - from md5sum command]

让我们尝试一下该find命令,看看它是否按照我们预期的那样输出所有内容。

[~/somedir]:$ find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \;

1752
1441609114
1441609114
1441609114
ASCII text
4fb6f64ce9d07be553a81644b17fe69b  ./README.md

./tuptime-install.sh
1649
1441609114
1441609114
1441609114
Bourne-Again shell script, ASCII text executable
9ee7ad860bfa049d1d5f589fba218c6a  ./tuptime-install.sh

处理线条

解析这些内容时,有很多地方可能会出错。如果文件名中有空格怎么办?或者其他奇怪的字符怎么办?或者其他参数中也有空格怎么办?为了解决这个问题和其他问题,我明确使用了换行符。这样我们就可以读取整行并进行相应的处理。不需要进行特殊解析。(除了哈希部分,但我们稍后会讲到该部分)

while 循环将输入命令的输出find。while 循环将在剩下一行时运行。我们读取每个匹配项开头的空行。空行实际上并不是真正需要的,但我们将使用它来保持输出干净。

该脚本非常直观。它按照我们期望的顺序逐行读取行并将其放入变量中。之后,我们将其打印出来。

该命令的工作方式read是,如果给出了单个变量名,它将把整行读入给定的变量名。如果给出了多个变量,则行将用空格字符(默认情况下)分隔并放入给定的变量中。我们只将它用于命令,因为我们无法指定可以删除文件名的选项。我们可以从' 或md5sum中获取文件名,但由于 md5sum 出于效率原因没有省略它的选项,因此我们将使用那个。findstat

我还使用了unixtime时间戳格式,而不是人类可读的格式。在大多数情况下,如果可能的话,最好以最原始的形式保存数据。

剩下唯一要做的事情就是将数据放入数据库。

脚本输出示例

File path: ./README.md
File size: 1752
File times (access - modified - changed): 1441609114 - 1441609114 - 1441609114
MIME stuff: ASCII text
Hash: 4fb6f64ce9d07be553a81644b17fe69b

File path: ./tuptime-install.sh
File size: 1649
File times (access - modified - changed): 1441609114 - 1441609114 - 1441609114
MIME stuff: Bourne-Again shell script, ASCII text executable
Hash: 9ee7ad860bfa049d1d5f589fba218c6a

相关内容