1

我在 Bash 中创建和排序数组时遇到问题,该数组将其内容作为命令中的行,获取每行的某些部分并在将它们附加到数组中的每一行之前对其进行操作。

为了澄清,命令“bogoutil -d wordlist.db”以这种形式给出输出:

hello 428 3654 20151116

除了有几百万条这样的行。

我想将命令的每一行输出加载到一个数组中,将第一个数字的绝对值减去第二个数字,将该值附加到新数组中的行上,然后按该新值对新数组进行排序。

我遇到的问题是我怀疑 IFS 需要更改为 "\n" 以将 bogoutil 输出的每一行放入一个数组中,但随后它需要再次更改以标记每行中的第二个和第三个整数. 到目前为止,很难弄清楚我的错误是什么,因为数组中有超过 1000 万行,但我可以从输出中看出我得到的不是我应该得到的 - 我认为它只是列出每一行并且没有正确标记。通常它会运行一段时间,将大量输出打印到 shell 中,这绝对不是我所期望的(我认为它只是一些标记,但绝对不是全部)然后打印

sort: cannot read: resultsarray: No such file or directory

这是我到目前为止所写的

#!/bin/bash

IFS=$"\n" #set the IFS so it tokenises each line in the command
for i in $( bogoutil -d wordlist.db )
    do 
            echo $i
            OUTPUT=( ${i// \n} ) #swap out space for a newline so i can
                                 #tokenise by spaces
            BAD=${OUTPUT[1]}
            echo $BAD
            GOOD=${OUTPUT[2]}
            echo $GOOD
            DIFF=$GOOD-$BAD
            echo $DIFF
            if [ "$DIFF" -lt "0" ]
            then
                    DIFF=$DIFF \* -1
            fi
            NEWOUT="$OUTPUT $DIFF" #append the abs of the difference to
                                   #the line so i can sort by it
            resultsarray[i]=$NEWOUT
    done

sort -t " " -k 5 -g resultsarray

echo "${resultsarray[@]:0:10}"

任何帮助将不胜感激。我真的很难过,不知道为什么它不起作用。我怀疑这与我尝试标记每一行输出的方式有关,但我不确定。另一种可能性(假设它列出了一段时间的标记然后停止)是数组中的元素太多并且分配的空间不足。有这种可能吗?

在此先感谢,非常感谢您提供的任何帮助。

编辑:澄清预期的输入和输出。

样本输入将是

hello 4 1 20151116
goodbye 0 256 20151116
grant 428 3654 20151116

预期的输出将是

grant 428 3654 20151116 3226
goodbye 0 256 20151116 256
hello 4 1 20151116 3

如您所见,它按第一个和第二个数字之差的绝对值排序。数据集中没有负数,最低的是 0。

编辑:下面的 awk 解决方案效果很好!我不确定如何使用 Bash,但我怀疑 bash 不是正确的方法,无论如何使用 awk 可能更好。感谢所有的帮助,非常感谢!

4

1 回答 1

0

如果我正确理解了您的问题(这就是为什么包含来自您的样本输入的样本输出如此​​重要的原因),

 cat tst.file
 hello 428 3654 20151116
 goodby -428 3655 20151116

这是假设输入不是制表符分隔的数据。此外,如果您想用稍大的数据集更新您的问题,我很乐意尝试确认这是一个很好的解决方案。您可能还希望从输入中包含所需的输出;-)(提示,提示)。

 awk '
    function abs( num) {return (num >0) ? -num : num;} 
    {res=abs($2)+$3 ; print $0 "\t" res}' tst.file \
 | sort -t"${tabChar}" -k2n

产生像这样的输出

hello 428 3654 20151116    3226
goodby -428 3655 20151116  3227

一些sort程序支持-t"\t"为排序分隔符定义 tabChar。我的不是这样,我单独定义它,就像tabChar=" "在 dbl-quotes 中的一个真正的选项卡 Char 一样。


正如我在评论中提到的,您可以在上面进行简化(假设程序中的 std 行结尾),例如:

bogoutil -d wordlist.db \
| awk '....' \
| sort -k2n

IHTH

于 2015-11-17T23:41:51.563 回答