我有大约 185000 个大量文件,其中 99% 以 6 位数字开头,后跟下划线和其他随机符号和随机扩展名
312095_ck_image-24-10-20-11-29-1.jpeg
312095_ck_image-24-10-20-11-29-2.jpeg
312095_ck_image-24-10-20-11-29.jpeg
基本上这个六位数字是一个用户ID(由某些后端oracle数据库给出的用户ID),
每个用户ID可以在目录中出现多次。我还有一个每行一个 6 位数字的文本文件(大约 18000 个数字)。是否可以将文件目录与文本文件的内容相匹配。因此,如果文件以文本文件中的数字开头,我希望将其移动到另一个目录(无论名称或扩展名的其余部分如何),以便我稍后可以删除该文件夹。我只想将所有匹配的文件放在一个文件夹中,这样我就可以删除整个文件夹而不是每个单独的文件。这在 Linux 中是否可能(在 shell 中或通过从源代码安装/构建其他 Linux 程序)。操作系统版本是 RHEL Linux 6。如果这使这更容易,我可以将目录中的文件列表加载到数据库表中,并将其与文本文件中的数字列表进行匹配,这样我就可以准确地知道是什么要重新/移动的文件的名称。我只是不知道如何将该列表提供给 mv 命令,以便它可以移动/删除文件。实现它的最简单方法是什么?因此,如果我的实际文件夹是/new_upload/entrants/
,并且我有一个名为 junk 的空文件夹,与参赛者处于同一级别 /new upload/junk
,并且如果 312095 出现在我想要执行的 ids 列表中
mv 312095_* /new_upload/junk
[idis] entrants# sh -h
sh-4.1#
[idis] entrants# $SHELL --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
答案1
在 GNU 系统上,你可以这样做:
find . -type f -print0 |
LC_ALL=C gawk -F/ '
!list_processed {user[$0]; next}
match($NF, /^([0-9]{6})_/, f) && f[1] in user
' user-list.txt list_processed=1 RS='\0' ORS='\0' - |
xargs -r0 mv -it /where/to/move/them --
答案2
你有 GNU bash
,所以使用 shell 结构和 GNU 很简单grep
:
#!/bin/bash
for file in *; do
match=$(echo "${file}" | grep -o '^[[:digit:]]\{6\}')
if [[ -z "${match}" ]] ; then
# File did not start with 6 digits, delete
rm -- "${file}"
else
grep -q -F ${match} numbersfile.txt || rm -- "${file}"
fi
done
那是:
- 循环遍历所有文件名
- 对于每个文件名,检查
grep
它是否以 6 位数字开头 - 如果没有,删除文件
- 如果是,请检查
grep
匹配的数字是否在numbersfile.txt
- 如果没有,删除文件
(如果你想在删除之前进行测试,只需替换rm
为echo
,你就会得到所有要删除的文件的列表)