我正在尝试调整大于特定尺寸的照片,为过去10年内系统收集的数十万张照片调整大小。我正在使用find
和imagemagick
我写了这个脚本来做它。
#!/bin/bash
ResizeSize="1080^>"
Processing=0
find . -type f -iname '*JPG' -print0 | \
while IFS= read -r -d '' image; do
((Processing++))
echo Processing file: $Processing
echo Resizing """$image"""
convert """$image""" -resize $ResizeSize """$image""___"
if [ $? -eq 0 ] ; then
rm """$image"""
if [ $? -eq 0 ] ; then
mv """$image""___" """$image"""
else
echo something wrong with resize
exit 1
fi
done
该脚本适用于少量文件,但需要很长时间才能启动大量文件。我已经在命令行find . -type f -iname '*JPG' -print0
vs find . -type f -iname '*JPG'
上进行了测试。后者在几秒钟内找到文件,但前者需要几分钟才能找到任何内容?不幸的是,-print0
是处理带有特殊字符的文件名所必需的(在我的情况下主要是空格)。如何让这个脚本更高效?
答案 0 :(得分:0)
我无法重现您遇到的行为,但可以想到两种可能的解释。
首先,您可能会遇到页面(磁盘)缓存的积极影响。
第一次调用find
时,它会遍历文件(inode中的元数据),实际上是通过内核syscall
从数据媒体(HDD)读取的。但是内核(透明地find
或其他应用程序)也将数据存储在未使用的内存区域中,这些区域充当缓存。如果稍后再次读取此数据,则可以从内存中的此缓存快速读取该数据。这称为page caching。
因此,假设您使用相同的条件搜索相同的文件,您对find
的第二次调用(无论使用什么输出分隔符)将快得多。
第二次,因为find
的输出可能会被缓冲,如果您的文件位于许多不同的位置,可能需要一些时间才能实际输出{{1}命令。此外,如果输出是行缓冲的,那么这将解释为什么while
变量需要更长的时间来产生第一个输出(因为根本没有行)。
您可以尝试通过-print0
命令运行带有无缓冲输出的find
:
stdbuf
还有一件事,与此无关;要加快stdbuf -o0 find . -iname '*.jpg' -type f -print0 ...
搜索速度,您可能需要考虑将其称为:
find
此处我们在find . -iname '*.jpg' -type f -print0
测试之前放置了-iname
测试,以避免在每个文件上调用-type
。如果可能的话,更好的方法是一起删除stat(2)
测试。