【问题标题】:Array handling using Awk [closed]使用 Awk 处理数组 [关闭]
【发布时间】:2013-07-19 17:33:08
【问题描述】:

我有两个输入文件,一个只包含数字,例如

range.txt

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11    
12  
13  
14  
15  
16  
17  
18  

另一个文件有要求。例如

requirements.txt

2s 4m  
1s 10m  

这意味着 2 组每组 4 名成员和 1 组 10 名成员。

输出应该是这样的:

There is 1 apple;  
There are 2 mangoes and 1 apple;   
There are 3 mangoes and 1 apple;   
There are 4 mangoes and 1 apple;  
There is 5 apple;  
There are 6 mangoes and 5 apple;  
There are 7 mangoes and 5 apple;  
There are 8 mangoes and 5 apple;  
There is 9 apple;  
There are 10 mangoes and 9 apple;  
There are 11 mangoes and 9 apple;  
There are 12 mangoes and 9 apple;  
There are 13 mangoes and 9 apple;  
There are 14 mangoes and 9 apple;  
There are 15 mangoes and 9 apple;  
There are 16 mangoes and 9 apple;  
There are 17 mangoes and 9 apple;  
There are 18 mangoes and 9 apple;     

如何使用 awk 和 shell 脚本(甚至 perl)实现这一点?我们拥有的 awk 版本是 /usr/xpg4/bin/awk。我不熟悉数组,这就是为什么需要一些帮助。
谢谢!

PS:刚刚更新了将苹果“价值”附加到芒果“价值”的要求。

【问题讨论】:

  • 很难理解这两个文件是如何组合在一起形成您的输出的。你能再澄清一下吗?
  • Florin,o/p 文件只使用 requirements.txt 和 range.txt 文件生成的值。

标签: perl shell unix sed awk


【解决方案1】:
awk '
    {
        sets = 0+$1
        mbrs = 0+$2
        for (i=1; i<=sets; i++)
            groups[idx++] = mbrs
    }

    END {
        for (idx in groups) {
            getline < range
            printf "There is %d apple;\n", $1
            for (i=2; i<=groups[idx]; i++) {
                getline < range
                printf "There are %d mangoes;\n", $1
            }
        }
    }
' range=range.txt requirements.txt

perl -Mautodie -nE '
    BEGIN { open $range, "<", shift }
    next unless /(\d+)s (\d+)m/;
    ($sets, $mbrs) = ($1, $2);
    for $i (1..$sets) {
        chomp( $n = <$range> );
        say "There is $n apple;";
        for $j (2..$mbrs) {
            chomp( $n = <$range> );
            say "There are $n mangoes;";
        }
    }
' range.txt requirements.txt

【讨论】:

  • +1 用于理解需求并回答它。
  • 谢谢格伦,这个也很完美。但是,我只需要将苹果“计数”附加到“芒果”计数,如下所示。希望这不会有什么大不了的!
  • 应该没什么大不了的。事实上,我将把它作为练习留给读者;)您所要做的就是记住打印苹果线时的值,并将其添加到每个芒果的输出中。你应该做一些的工作。
  • 谢谢格伦!我将开始研究数组。那是一个好的开始。感谢您的帮助。
【解决方案2】:

awk:

awk -F "[sm]" '{ for (set=1; set<=$1; set++) {
                   getline ct < "range.txt"
                   print "There is " ct " apple;"
                   for (member=1; member<=$2; member++) {
                     getline ct < "range.txt"
                     print "There are " ct " mangoes;"
                   }
                 }
               }' requirements.txt

这会使用sm 字符作为分隔符来解析requirements.txt。当它遍历这两个数字时,它使用range.txt 中的每一行作为ct 变量以显示在输出中。

【讨论】:

  • Greg,效果很好。但是我刚刚意识到我们需要采用稍微不同格式的 o/p,在这种格式中,我们将“苹果”计数附加到“芒果”计数上,如上所示(抱歉,我不能更好地缩进它!)我希望这不会对脚本造成很大的改变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 2011-07-04
  • 2013-07-18
相关资源
最近更新 更多