首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在子目录中查找最大值和最小值(对于shell脚本,小于10秒)

在子目录中查找最大值和最小值(对于shell脚本,小于10秒)
EN

Stack Overflow用户
提问于 2013-11-30 22:43:50
回答 3查看 122关注 0票数 0

我有几个这种类型的文件:

代码语言:javascript
复制
Sensor   Location              Temp       Threshold
------   --------              ----       ---------
#1        PROCESSOR_ZONE       23C/73F    62C/143F 
#2        CPU#1                30C/86F    73C/163F 
#3        I/O_ZONE             32C/89F    68C/154F 
#4        CPU#2                22C/71F    73C/163F 
#5        POWER_SUPPLY_BAY     17C/62F    55C/131F 

在几个子目录中大约有124630个,我试图确定PROCESSOR_ZONE的最高和最低温度。下面是我目前的脚本:

代码语言:javascript
复制
#!/bin/bash

max_value=0
min_value=50

find $1 -name hp-temps.txt -exec grep "PROCESSOR_ZONE" {} + | sed -e 's/\ \+/,/g' | cut -d, -f3 | cut -dC -f1 | while read current_value ; 
do
    echo $current_value;
done

我的脚本后面的输出:

代码语言:javascript
复制
30
28
26
23
...

我的脚本还没有完成,它设置了10分钟来显示所有的温度。我认为要到达那里,我必须将我的命令的结果放在一个文件中,对其进行排序,并返回第一行,这是最大值,最后一行是最小值。但是我不知道怎么做。

EN

回答 3

Stack Overflow用户

发布于 2013-11-30 22:54:27

而不是这一位:

代码语言:javascript
复制
... | while read current_value ;
do
    echo $current_value;
done

只需将cut之后的输出定向到一个文件:

代码语言:javascript
复制
... > temperatures.txt

如果您需要对它们进行排序,请先对它们进行排序:

代码语言:javascript
复制
... | sort -n > temperatures.txt

那么文件的第一行将是返回的最低温度,最后一行将是最高温度。

性能建议:

find命令在每个文件上运行一个新的grep进程。如果您的目录中有数十万个这样的文件,它将运行grep数十万次。您可以通过告诉find对每批几千个文件运行一次grep命令来加快速度:

代码语言:javascript
复制
find $1 -name hp-temps.txt -print | xargs grep -h "PROCESSOR_ZONE" | sed ...

find命令在标准输出上打印出文件名;xargs命令读取这些文件名,并立即对一批文件运行grep。grep的-h选项表示“输出中不包含文件名”。

如果有数以千计的文件要处理,以这种方式运行它将大大加快搜索速度。

票数 0
EN

Stack Overflow用户

发布于 2013-12-02 06:53:57

如果你的脚本很慢,你可能想先分析哪个命令是慢的。例如,在有很多文件的Windows/Cygwin上使用find会很慢。

Perl可以完美地解决您的问题:

代码语言:javascript
复制
find $1 -name hp-temps.txt -exec perl -ne '/PROCESSOR_ZONE\s+(\d+)C/ and print "$1\n"' {} +

通过这种方式,您可以同时对许多文件执行(Perl)正则表达式匹配。括号与温度数字(\d+)相匹配,$1引用该数字。and确保在匹配成功时仅执行print only。

您甚至可以考虑使用opendirreaddir递归地下降到Perl中的目录中,以摆脱查找,但它不会更快。

要获取最小值和最大值,请执行以下操作:

代码语言:javascript
复制
    find $1 -name hp-temps.txt -exec perl -ne 'if (/PROCESSOR_ZONE\s+(\d+)C/){ $min=$1 if $1<$min or $min == undef; $max=$1 if $1>$max }; sub END { print "$min - $max\n" }' {} +

使用终端上的100k+输出行,这应该会节省相当多的时间。

票数 0
EN

Stack Overflow用户

发布于 2013-12-23 04:51:36

代码语言:javascript
复制
#!/bin/bash

max_value=0
min_value=50

find $1 -name file.txt -exec grep "PROCESSOR_ZONE" {} + | sed -e 's/\ \+/,/g' | cut -d, -f3 | cut -dC -f1 |
{
while read current_value ; do
    #For maximum
    if [[ $current_value -gt $max_value ]]; then
        max_value=$current_value
    fi

    #For minimum
    if [[ $current_value -lt $min_value ]]; then
        min_value=$current_value
    echo "new min $min_value"
    fi
done

echo "NEW MAX : $max_value °C"
echo "NEW MIN : $min_value °C"
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20301544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档