提问人:Batavia 提问时间:8/31/2023 最后编辑:Jason AllerBatavia 更新时间:9/6/2023 访问量:111
Bash - 删除大目录中的文件
Bash - Delete files in large directories
问:
我必须删除非常大的目录(500k 文件)中的文件,如下所示:
Fiche_8317.doc
Fiche_8318.doc
Fiche_8319.doc
我编写了一个循环来读取一个文件,该文件给了我必须删除的名称:*deletedFiles.txt
AAA;ZQ;00008319;2011-05-18;ACTA;RR02000354090127104747.doc
AAA;ZQ;00008320;2011-05-18;ACTA;RR02000354090127104747.doc
AAA;ZQ;00008321;2011-05-18;REDA;RR02000354090127104747.doc
AAA;ZQ;00008322;2011-05-18;ITAC;RR02000354090127104747.doc
我尝试了这样的循环(不是我的真实代码,我更改了变量):
while IFS=";" read -r idt surname
do
Echo $idt " " $surname
#Supress leading 0 and delete
find $DataPath/target/ -type f -name Fiche_"$((10#$idt))".* -delete
done < <(cut -d ";" -f 3,6 $DataPath/*deletedFiles.txt)
这段代码可以工作,但速度非常慢,在我的 Linux 服务器上每个文件超过 2 分钟。
目录中每个文件只有 1 个文件。idt
我可以改进一下吗? 我正在寻找一个更快的解决方案。
不幸的是,我只能使用 bash,因为我公司的调度程序只能与 bash 一起使用。
非常感谢
答:
1赞
Fravadona
9/1/2023
#1
花费大量时间的是遍历目录以查找要删除的文件。为了加快速度,您可以调用一次,使用 GNU 过滤文件路径并调用find
awk
rm
xargs -0
find "$DataPath"/target -type f -print0 |
awk -v ORS='\0' '
FNR == NR { prefixes[sprintf("Fiche_%d", $3)]; next }
match($NF, /^[^.]+/) && (substr($NF,RSTART,RLENGTH) in prefixes)
' FS=';' "$DataPath"/deletedFiles.txt RS='\0' FS='/' - |
xargs -0 rm --
0赞
DevSolar
9/6/2023
#2
希望文件名中的星号是错别字:*deletedFiles
cut -d';' -f3 "$DataPath/deletedFiles.txt" | \
sed "s/^0*\(.*\)/rm \"$DataPath/target/Fiche_\1.doc\"/" | \
source /dev/stdin
cut -d';' -f3
从输入中获取第三个字段。我从你的例子中删除了这句话,因为你正在寻找性能。echo
sed s/^0*\(.*\)/...
从该字段中剥离前导零....../rm $DataPath/target/Fiche_\1.doc/
...在命令、路径和前面附加 。rm
.doc
source /dev/stdin
从当前 shell 中的管道(命令序列)运行结果。(此功能在 bash v4.0 之前已出现错误。rm
如果您将多个文件放到一个命令行上以由单个文件删除,您可能会从中挤出更多的性能,但我不确定是否值得在性能和维护方面增加复杂性。rm
评论
.../target/
find
find
rm $DataPath/target/Fiche_${idt}.*
find
find
find
Fiche_8319.doc
find
deletedFiles.txt
bash
Perl
Python
find
cut