【问题标题】:Discrepancy in minimum value method最小值法的差异
【发布时间】:2014-06-09 04:51:20
【问题描述】:

Linux 新手在这里和第一篇文章。请原谅我不够清楚。

我认为这是一个简单的最小值问题,两种不同方法之间存在差异:逐个文件 awking 和使用通配符 awking。

我目前有大约 20,000 个文件(并且还在增长),我只想在第二列中找到总体最小值。这些文件都具有相同的前缀,并且位于执行脚本的下一级目录中,因此我使用通配符快速完成任务。

例子:

awk 'min=="" || $2 < min {min=$2} END{print min}' */myfile.10*

执行大约需要 14 秒,但它没有找到真正的最小值。

或者,我逐步浏览了每个目录的每个文件,我似乎找到了正确的最小值:

   min=1000000000.0
   for dir in `ls -d *run*/`; do
     minlocal=1000000000.0
     for file in `ls -1 ${dir}myfile.*`; do
       for val in `awk 'NR==1 {print $2}' $genfile`; do
         compare_result=`echo  $minlocal" > "$val | bc`
         if [ $compare_result -eq 1 ]; then
           minlocal=$val
           fileminlocal=$file
           compare_result=`echo $min" > "$minlocal | bc`
           if [ $compare_result -eq 1 ]; then
             min=$val
             filemin=$file
           fi
         fi
       done
     done
     compare=`echo $min" > "$minlocal | bc`
     if [ $compare -eq 1 ]; then
       echo "  Error finding lowest chi^2 in " $fileminlocal
       echo "  Skipping..."
     else
       echo "  Lowest value (" $minlocal ")found in " $fileminlocal
     fi
   done

这种方法可以正确找到总体最小值,但需要 4 分钟。我知道遍历每个文件需要更多时间,但为什么使用通配符会导致任务失败?

【问题讨论】:

  • 我对某个文件进行了测试,您的 awk 确实有效。对我来说,它给出了正确的值。 true minimum 是什么意思?你可以重写一些:awk '!min || $2&lt;min {min=$2;f=FILENAME} END{print min,f}' 来获取文件名。
  • 如果您没有回复,我们如何提供帮助?
  • 感谢回复(我已经去睡觉了)。

标签: awk minimum


【解决方案1】:

您的 awk 脚本可能正在对每个 min 值进行字符串而不是数字比较,特别是因为脚本中的第一个语句明确地是字符串比较。要强制使用数字,请将其更改为:

awk 'min=="" || $2 < min+0 {min=$2} END{print min}' */myfile.10*

Awk 将所有输入视为数字字符串类型,这是您第一次使用该输入的方式,这允许 awk 确定它实际上是数字还是字符串。

【讨论】:

  • 或者只是+min而不是min+0
  • 我发现x &lt; +y 的语法不如x &lt; y+0 清晰。我想是 YMMV。
  • awk 'min=="" || $2 /myfile.10 和
  • 对奇怪的 cmets 感到抱歉。我正在学习该网站的来龙去脉...不幸的是 awk 'min=="" || $2 /myfile.10 和 awk 'min=="" || $2 /myfile.10 给出相同的结果。我知道最小值是 6901.7532(这是按目录搜索时返回的值)但是这两种方法都返回 6901.7536。
  • 您将不得不发布一些可以重现问题的示例输入。我怀疑您的一个或多个文件不符合您期望的格式。也许它们是用 DOS 创建的,所以它们包含虚假的 control-M?尝试在每个第一次运行 dos2unix
【解决方案2】:

我不确定您为什么会遇到您提到的差异,但我建议您使用 sort 来解决此问题:

sort -n -k2 */myfile.10*

执行数字排序,使用第二列作为键。 sort 将输出所有文件中的所有行,所以也许你可以使用 awk 只打印你感兴趣的值:

sort -n -k2 */myfile.10* | awk 'NR==1 {print $2; exit}'

将打印第一行第二列中的值,然后退出。

【讨论】:

  • 这确实有效,但我怀疑它比使用 awk 完成整个事情的效率要低得多,因为它需要对 whole 列表进行排序,而不仅仅是获得最小值。我将把它留在这里,因为它是一个有效的解决方案,但我建议不要将其用于大量数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多