找出列中每个字段的范围

时间:2019-06-05 22:01:04

标签: indexing awk range tcl

我有一列看起来像这样:

A 1
B 3
C 5
D 4
E 7
F 1
G 1
H 3

对于第2列中的每个归档字段,我想上下计算3个视场半径的范围(最大值-最小值)。

A range(1 3 5 4)
B range(1 3 5 4 7)
C range(1 3 5 4 7 1)
D range(1 3 5 4 7 1 1)
E range(  3 5 4 7 1 1 3)
F range(    5 4 7 1 1 3)
G range(      4 7 1 1 3)
H range(        7 1 1 3)

如何在awk中做到这一点?

我可以使用以下方法在perl中做同样的事情:

my $set_size = @values;
for ( my $i = 0 ; $i < $set_size ; $i++ ) {
    my $min = $i - 4;
    if ( $min < 0 ) { $min = 0; }
    my $max = $i + 4;
    if ( $max > ( $set_size - 1 ) ) { $max = $set_size - 1; }
    my $min_val = $values[$min];
    my $max_val = $values[$min];
    for ( my $j = $min ; $j <= $max ; $j++ ) {
        if ( $values[$j] <= $min_val ) { $min_val = $values[$j]; }
        if ( $values[$j] >= $max_val ) { $max_val = $values[$j]; }
    }
    my $range = $max_val - $min_val;
    printf "$points[$i] %.15f\n", $range;
}

4 个答案:

答案 0 :(得分:0)

idk的确切含义是I want to calculate the range (max-min) of 3 field radius up and down.,但要从发布的输入中获取发布的输出,则是:

$ cat tst.awk
{
    keys[NR] = $1
    values[NR] = $2
}
END {
    range = 3
    for (i=1; i<=NR; i++) {
        min = ( (i - range) >= 1  ? i - range : 1  )
        max = ( (i + range) <= NR ? i + range : NR )
        printf "%s range(", keys[i]
        for (j=min; j<=max; j++) {
            printf "%s%s", values[j], (j<max ? " " : ")\n")
        }
    }
}
$
$ awk -f tst.awk file
A range(1 3 5 4)
B range(1 3 5 4 7)
C range(1 3 5 4 7 1)
D range(1 3 5 4 7 1 1)
E range(3 5 4 7 1 1 3)
F range(5 4 7 1 1 3)
G range(4 7 1 1 3)
H range(7 1 1 3)

答案 1 :(得分:0)

您的示例perl不会打印出示例输出,这似乎有所不同...因此,这就是我在perl中执行的操作:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw/say/;
use List::Util qw/min max/;

my (@col1, @col2);
while (<>) {
    chomp;
    my ($v1, $v2) = split;
    push @col1, $v1;
    push @col2, $v2;
}

my @prefix;
for my $i (0 .. $#col1) {
    my @range = @col2[max($i - 3, 0) .. min($i + 3, $#col2)];
    push @prefix, ' ' if $i > 3;
    unshift @range, @prefix;
    say "$col1[$i] range(@range)"
}

运行它:

$ perl range.pl input.txt
A range(1 3 5 4)
B range(1 3 5 4 7)
C range(1 3 5 4 7 1)
D range(1 3 5 4 7 1 1)
E range(  3 5 4 7 1 1 3)
F range(    5 4 7 1 1 3)
G range(      4 7 1 1 3)
H range(        7 1 1 3)

但是,如果任何数字大于9,则格式将中断。

答案 2 :(得分:0)

自从您标记了

#!/usr/bin/env tclsh

lassign $argv file size

set fh [open $file r]
# assume exactly 2 space-separated words per line
set data [dict create {*}[split [read -nonewline $fh]]]
close $fh

set len [dict size $data]
set values [dict values $data]
set i 0

dict for {key _} $data {
    set first [expr {max($i - $size, 0)}]
    set last  [expr {min($i + $size, $len)}]
    puts [format "%s range(%s%s)" \
        $key \
        [string repeat "  " $first] \
        [lrange $values $first $last] \
    ]
    incr i
}

输出

A range(1 3 5 4)
B range(1 3 5 4 7)
C range(1 3 5 4 7 1)
D range(1 3 5 4 7 1 1)
E range(  3 5 4 7 1 1 3)
F range(    5 4 7 1 1 3)
G range(      4 7 1 1 3)
H range(        7 1 1 3)

答案 3 :(得分:-5)

TXR在shell提示符下:

      X2YR X3YR X5YR X7YR X10YR X30YR
X2YR    NA   NA   NA   NA    NA    NA
X3YR    NA   NA   NA   NA    NA    NA
X5YR    NA   NA   NA   NA    NA    NA
X7YR    NA   NA   NA   NA    NA    NA
X10YR   NA   NA   NA   NA    NA    NA
X30YR   NA   NA   NA   NA    NA    NA