.sh 文件用于计算文件数量

.sh 文件用于计算文件数量

朋友们,

我有一个小型的基本 shell 脚本,用于压缩目录和子目录中的文件。但是,我需要添加一个计数器,以便只压缩一定数量的文件(例如 50 个文件)。我无法完成,请提供建议。请在下面找到我的脚本。

#!/bin/bash
BASEDIR=/home/tmp
cd "${BASEDIR}"
pwd

for i in `find .  -name *.jpg -type f -print -mtime +30`
do
  zip ${i%.*} $i
  echo "Process Completed"
done

请指教?非常感谢您的帮助。

答案1

有几件事需要解决:

  • 不要使用反引号;$(...)现在通常更倾向于使用反引号,特别是因为它们可以处理嵌套引用。这里没有问题,但要注意这一点
  • find应与循环一起使用,while以对文件名进行复杂的处理。While 循环也有助于模仿 C 风格的 for 循环,事实上,在编程中,您可以在任一循环中实现相同的行为,这是一个常见的概念。
  • 如果要添加到现有 zip 文件,请使用-u标志进行更新,如“$current_file”zip -u zipfile.zip

因此,你的脚本最好写成

#!/bin/bash
# using capitals for variable names
# can be confusing and interfere with env
# or shell variables
basedir=/home/tmp
cd "${basedir}"
# You can use variable instead of pwd command
printf "Current working directory:%s\n" "$PWD"

counter=0    
# pipelines can be broken to multiple lines
find .  -name '*.jpg' -type f -print0 -mtime +30 |
while IFS= read -r f_name; do
    counter=$((counter+1))
    zip u ${i%.*} "$f_name"
    # This is where you check for number of files processed
    if [ "$counter" -eq 50 ]; then
        break
    fi
done

如果这太冗长和冗长,我们可以用标志来玩一点find-exec但问题是我们不能在-exec调用之间共享变量。因此我们可以使用临时文件。我们还需要以某种方式停止在所有大于限制的文件上find调用我们的-exec进程,这样我们就可以杀死变量指定的 shell 的父进程$PPID

cd "$basedir"
find -type f -name '*.jpg' -mtime +30  -exec bash -c '
    f=/tmp/zip.counter; 
    [ -e "$f" ] && c=$(cat /tmp/zip.counter);
    c=$((c+1));
    [ "$c" -ge 50 ] && kill $(awk "/^Pid:/ {print $2}");
    zip u ${i%.*} "$1";
    echo "$c" > "$f"' sh {} \; && rm /tmp/zip.counter

当然,这个解决方案不太实用,而且可以说比while循环的可读性更低。这只是为了好玩。

相关内容