linux - 非常慢的脚本

标签 linux bash shell unix scripting

我有一个问题。我需要编写一个 bash 脚本来查找给定路径中的所有文件和目录,并显示有关结果的一些信息。允许时间:30 秒。

#!/bin/bash

DIRS=0
FILES=0
OLD_FILES=0
LARGE_FILES=0
TMP_FILES=0
EXE_FILES=0
IMG_FILES=0
SYM_LINKS=0
TOTAL_BYTES=0

#YEAR_AGO=$(date -d "now - 1 year" +%s)
#SECONDS_IN_YEAR=31536000

function check_dir {
    for entry in "$1"/*
    do
        if [ -d "$entry" ]; then
            ((DIRS+=1))
            check_dir "$entry"
        else if [ -f "$entry" ]; then
                ((FILES+=1))
                #SIZE=$(stat -c%s "$entry")
                #((TOTAL_BYTES+=SIZE))
                #CREATE_DATE=$(date -r "$entry" +%s)
                #CREATE_DATE=$(stat -c%W "$entry")
                #DIFF=$((CREATE_DATE-YEAR_AGO))
                #if [ $DIFF -ge $SECONDS_IN_YEAR ]; then
                #   ((OLD_FILES+=1))
                #fi
             fi

        fi
    done
}

if [ $# -ne 2 ]; then
    echo "Usage: ./srpt path emailaddress"
    exit 1
fi

if [ ! -d $1 ]; then
    echo "Provided path is invalid"
    exit 1
fi

check_dir $1

echo "Execution time $SECONDS"
echo "Dicrecoties $DIRS"
echo "Files $FILES"
echo "Sym links $SYM_LINKS"
echo "Old files $OLD_FILES"
echo "Large files $LARGE_FILES"
echo "Graphics files $IMG_FILES"
echo "Temporary files $TMP_FILES"
echo "Executable files $EXE_FILES"
echo "Total file size $TOTAL_BYTES"

以下是使用上面的注释行执行的结果:

Execution time 1
Dicrecoties 931
Files 14515
Sym links 0
Old files 0
Large files 0
Graphics files 0
Temporary files 0
Executable files 0
Total file size 0

如果我要删除来自

的评论
SIZE=$(stat -c%s "$entry")
((TOTAL_BYTES+=SIZE))

我得到了:

Execution time 31
Dicrecoties 931
Files 14515
Sym links 0
Old files 0
Large files 0
Graphics files 0
Temporary files 0
Executable files 0
Total file size 447297022

31 秒。我怎样才能加快我的脚本? 再过 +30 秒可以找到创建日期超过一年的文件

最佳答案

通常情况下,在 shell 中使用循环表明您采用了错误的方法。

shell 首先是运行其他工具的工具。

虽然它可以进行计数,但 awk 是一个更好的工具。

虽然它可以列出和查找文件,但 find 更擅长。

最好的 shell 脚本是那些设法让一些工具为任务做出贡献的脚本,而不是那些依次启动数百万个工具并且所有工作都由 shell 完成的脚本。

在这里,通常更好的方法是让 find 找到文件并收集您需要的所有数据,然后让 awk 处理它并返回统计信息。这里使用 GNU find 和 GNU awk(对于 RS='\0')和 GNU date(对于 -d):

find . -printf '%y.%s.%Ts%p\0' |
  awk -v RS='\0' -F'[.]' -v yearago="$(date -d '1 year ago' +%s)" '
    {
      type[$1]++; 
      if ($1 == "f") {
        total_size+=$2
        if ($3 < yearago) old++
        if (!index($NF, "/")) ext[tolower($NF)]++
      }
    }
    END {
      printf("%20s: %d\n", "Directories", type["d"])
      printf("%20s: %d\n", "Total size", total_size)
      printf("%20s: %d\n", "old", old)
      printf("%20s: %d\n", "jpeg", ext["jpg"]+ext["jpeg"])
      printf("%20s: %d\n", "and so on...", 0)
    }'

关于linux - 非常慢的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17265044/

相关文章:

bash - Docker .bashrc 服务 HTTP 请求失败

java - 如何使用 Java 通过 Windows/cygwin 执行 unix 命令

linux - Linux 中 while 循环的问题

php - 如果 $arr1 和 $arr2 的元素具有相同的值,有没有办法合并 array_count_values($arr1) 和 array_count_values($arr2) 的结果?

java - 可以在 headless (headless)Linux环境下截图吗?

bash - 使用 Perl 特殊字符替换 Perl 中的变量

bash - 在 bash 中将时间戳转换为日期

python - Python 3.6 shell 中可点击的 html 链接?

linux - 加速 Linux 应用程序的读取

c - 我正在用C语言制作linux命令程序。我想知道代码出了什么问题?