0

我有一个非常长的文件列表,存储在我想在我的驱动器上找到的文本文件(missing-files.txt)中。这些文件分散在我驱动器的不同文件夹中。我想获得任何可以找到的最接近的可用。

丢失文件.txt

wp-content/uploads/2019/07/apple.jpg
wp-content/uploads/2019/08/apricots.jpg
wp-content/uploads/2019/10/avocado.jpg
wp-content/uploads/2020/04/banana.jpg
wp-content/uploads/2020/07/blackberries.jpg
wp-content/uploads/2020/08/blackcurrant.jpg
wp-content/uploads/2021/06/blueberries.jpg
wp-content/uploads/2021/01/breadfruit.jpg
wp-content/uploads/2021/02/cantaloupe.jpg
wp-content/uploads/2021/03/carambola.jpg
....

这是我的工作 bash 代码:

while read p;
do
    file="${p##*/}"
    /usr/local/bin/fd "${file}" | /usr/local/bin/rg "${p}" | /usr/bin/head -n 1 >> collected-results.txt
done <missing-files.txt

我的 bash 代码中发生了什么:

  1. 我从我的文件列表中迭代
  2. 我使用FD ( https://github.com/sharkdp/fd ) 命令在我的驱动器中找到这些文件
  3. 然后我将它传送到RIPGREP ( https://github.com/BurntSushi/ripgrep ) 以过滤结果并找到最接近的匹配项。我正在寻找的匹配应该匹配相同的文件和文件夹结构。我只限制一个结果。
  4. 然后最后将其存储在另一个文本文件中,稍后我可以评估列表以进行下一步

我需要帮助的地方:

  1. 这是最有效的方法吗?我有超过 2,000 个文件需要查找。我对其他解决方案持开放态度,这是我刚刚划分的。
  2. 由于某种原因,我的编码坏了,它停止将结果返回到“collected-results.txt”。我的猜测是它在FD命令之后的第二个管道中的某个地方坏了。我没有设置任何条件以防它遇到错误或找不到文件,所以我很难确定。

附加信息:

  • 我正在使用 Mac,并在 Catalina 上运行
  • 显然这不是我的专业领域
4

3 回答 3

1

“失踪”听起来好像它们不存在于预期的地方。
是什么让你认为他们会在其他地方?

如果是,我会将文件名放在一个list.txt具有足够最小模式的文件中,以便从find.

$: cat list.txt
/apple.jpg$
/apricots.jpg$
/avocado.jpg$
/banana.jpg$
/blackberries.jpg$
/blackcurrant.jpg$
/blueberries.jpg$
/breadfruit.jpg$
/cantaloupe.jpg$
/carambola.jpg$

然后搜索整个机器,这将需要一些时间......

$: find / | grep -f list.txt
/tmp/apricots.jpg
/tmp/blackberries.jpg
/tmp/breadfruit.jpg
/tmp/carambola.jpg

或者如果你想要那些更长的部分路径,

$: find / | grep -f missing-files.txt

如果系统上确实存在这些文件,那应该会向您显示这些文件所在位置的实际路径。

于 2021-06-23T14:08:49.507 回答
0

根据我的理解,您想找到所有可能与目录结构匹配的文件:

path/to/file

所以它应该返回类似“/full/path/to/file”和“/another/full/path/to/file”的东西

使用一个简单的find命令,您可以获得符合此条件的所有文件的列表。

使用find您可以通过以下形式一次性搜索硬盘:

$ find -regex pattern

现在的想法是构建模式,我们可以从文件missing_files.txt. 该模式应该看起来像.*/\(file1\|file2\|...\|filen\). 所以我们可以使用以下awk方法来做到这一点:

$ sed ':a;N;$!ba;s/\n/\|/g' missing_files.txt

所以现在我们可以通过以下方式完成您所做的事情,但速度更快:

pattern="$(sed ':a;N;$!ba;s/\n/\|/g' missing_files.txt)"
pattern=".*/\($pattern\)"
find -regex "$pattern" > file_list.txt

为了找到文件,您现在可以执行以下操作:

grep -F -f missing_files file_list.txt

这将返回所有匹配的案例。如果你只想要第一种情况,即

awk '(NR==FNR){a[$0]++;next}{for(i in a) if (!(i in b)) if ($0 ~ i) {print; b[i]}}' missing_files file_list.txt
于 2021-06-23T10:09:02.107 回答
0

这是最有效的方法吗?

I/O 通常是最大的瓶颈。您正在运行一些软件fd来一次查找一个文件的文件。相反,运行它来一次查找所有文件- 对所有文件执行单一 I/O。在 shell 中,你会这样做:

find . -type f '(' -name "first name" -o -name "other name" -o .... ')'

如何从源文件列表中迭代并在我的磁盘驱动器上找到这些文件?

用于-path匹配完整路径。首先构建参数,然后调用find.

findargs=()
# Read bashfaq/001
while IFS= read -r patt; do
    # I think */ should match anything in front.
    findargs+=(-o -path "*/$patt")
done < <(
    # TODO: escape glob better, not tested
    # see https://pubs.opengroup.org/onlinepubs/009604499/utilities/xcu_chap02.html#tag_02_13
    sed 's/[?*[]/\\&/g' missing-files.txt
)
# remove leading -o
unset findargs[0]
find / -type f '(' "${findargs[@]}" ')'

研究主题:var=()- bash 数组、< <(...)带有进程替换的 shell 重定向以及何时使用它(bashfaq/024)、glob(参见man 7 glob)和man find.

于 2021-06-23T10:08:40.977 回答