我有一个与 MySQL DB 一起使用的文件存储目录。
目录中的某些文件是孤立的(即错误创建、在数据库中删除但不在磁盘上,否则不使用)。
我能够生成不带文件扩展名的此类文件列表,但现在将它们移出存储目录的最佳方法是什么。问题是存储是多级的,所以我必须先以某种方式找到每个文件。
孤立列表内容示例(共 200K 行):
10218
10219
10220
10221
10370
10371
10372
10373
10374
目录结构(示例):
如果你好奇我怎么会得到这样一个文件:
- 首先,将目录中的文件列表以递归方式保存为每个文件https://stackoverflow.com/a/5456136/505984
- 其次,使用 MySQL CLI 将数据库表 ID 转储到另一个文件(因为每个不带扩展名的文件名都与数据库记录 ID 匹配)
- 按照此处的建议对两个文件进行区分:https://stackoverflow.com/a/25407317/505984
我会集中精力做出选择,因为你说:
假设 bash shell:
澄清:
find
列出树中的所有文件。grep -f somefile
对 find 的管道输出应用过滤器<( something )
是一个临时文件awk '{print $0".pdf"}'
将孤儿列表中的每一行附加“.pdf”,因此 grep -f 与目录名称不匹配tmp/orphans
是孤儿的输入列表你的问题不太清楚,但假设你想
将没有扩展名的文件列表转换为可匹配任意扩展名的文件的模式列表
有效地将该模式列表传递给一系列
find
命令那么您可以尝试这样的操作,使用
sed
GNU parallel(可从 Ubuntu universe存储库获得):使用该
-X
选项,parallel
将尝试在每次调用中装入尽可能多的参数find
;参数来自三个输入源:字符串
-name
来自标准输入的一行
字符串
-o
从而构建一个看起来像这样的参数列表
-name '1406.*' -o -name '6179.*' -o -name '17526.*' -o ...
(您可以通过添加 parallel--dry-run
选项来验证)。最后一个-false
谓词会清除尾随字符-o
,-I%%
并将 parallel 的替换字符串从默认字符串更改{}
为不与 find 的默认替换字符串冲突。这肯定比运行
find
200,0000 次更有效率 - 但可能不如运行单个find
命令并 grepping 结果那么有效,正如此答案中所建议的那样。在我的 64 位 Ubuntu 24.04 VM 上,它设法将一个包含 200,0000 个整数 ID(从 bash$RANDOM
变量生成)的文件塞进大约 100 次调用中find
。如果成功识别文件,您可以更改
-print
为与您-exec mv -vnt "$dstdir" {} +
类似的内容并将其传递给via :srcdir
export dstdir=path/to/newdata
parallel
--env destdir
(您可以代替
-execdir
提供-exec
的$dstdir
是绝对路径)。