-print0选项

时间:2017-07-11 11:58:55

标签: bash find imagemagick

我正在尝试调整大于特定尺寸的照片,为过去10年内系统收集的数十万张照片调整大小。我正在使用findimagemagick

我写了这个脚本来做它。

#!/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是处理带有特殊字符的文件名所必需的(在我的情况下主要是空格)。如何让这个脚本更高效?

1 个答案:

答案 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)测试。