Hello everyone,
I am trying to create a script that will make a range or ranges based on a sorted list of numbers.
Eg. If the list is like
1
2
3
4
5
6
7
12
13
14
15
The output range should be:
1-7
12-15
Would be greateful if you could point me in the right direction,
Cheers,
rte
awk 'END {
if (prev != max)
print min, "-", prev
}
NR == 1 { min = $1 }
$1 != prev + 1 {
if (prev)
print min, "-", prev
min = $1;
}
{ prev = $1 }' infile
Does't work for me
I have created a file called test with the following content
1
2
3
4
5
10
11
12
but when I try to run
awk 'END {
if (prev != max)
print min, "-", prev
}
$1 != prev + 1 {
print min, "-", prev
min = $1
}
{
prev = $1
NR == 1 && min = $1
}' test
I get the error:
awk: syntax error near line 4
awk: bailing out near line 4
What am I doing wrong
Use nawk or /usr/xpg4/bin/awk on Solaris.
1 Like
Another approach:
awk '!r{r=n=$1;next}
++n!=$1{print r "-" --n;r=n=$1}
END{print r "-" n}
' file
Use nawk or /usr/xpg4/bin/awk on Solaris.
Wasn't something similar answered here?
... and therefore it's most probably a homework.
For the userland deviant who isn't satisfied with a simple, straighforward AWK solution ;):
echo '[dlb=Qdlb1+=MlPxlRx]sC [sbq]sM [lan[-]nlbpst]sP [q]sQ [dsasb]sR' | cat - data \
| sed '2,$s/-/_/; 2s/.*/& lRx/; 3,$s/.*/& lCx/; $s/.*/& lPx/' | dc
a = lower bound of sequence
b = upper bound of sequence
R = reset macro. Set a and b equal to the latest value read (this is the beginning of a new sequence).
M = max macro. Set the new upper bound of the sequence, b.
P = printing macro. Prints "a-b".
C = comparison macro. Determines if the newest value is part of an ongoing sequence. If it is, call the M (max) macro to store it in b. If it is not, call the P (print sequence) macro and then the R (reset) macro to begin a new sequence.
Q = quit macro
It handles negative values, sequences that span negative to positive (-1, 0, 1), and sequences which repeat the same value (1,2,3,3,3,4,5 => 1-5).
I'm a relative dc newbie, so if someone can do it better (with dc), I'd be interested in seeing your approach.
Test run:
$ cat data
-100
-99
-98
-97
-96
-4
-3
-2
-1
0
1
2
3
4
5
1
2
3
3
3
4
5
14
15
16
17
18
$
$ echo '[dlb=Qdlb1+=MlPxlRx]sC [sbq]sM [lan[-]nlbpst]sP [q]sQ [dsasb]sR' | cat - data \
> | sed '2,$s/-/_/; 2s/.*/& lRx/; 3,$s/.*/& lCx/; $s/.*/& lPx/' | dc
-100--96
-4-5
1-5
14-18
Regards,
Alister
#!/usr/local/bin/perl
use strict;
use warnings;
my $count=0;
my @arr=();
my @data = <DATA>;
foreach my $rec (@data) {
$count++;
chomp $rec;
if ($rec == $data[-1]) {
if ($rec-1 != $arr[-1]) {
print "$arr[0]-$arr[-1]\n";
print "$rec-$rec\n";
exit; }
else {
push @arr, $rec;
print "$arr[0]-$arr[-1]\n";
exit; }
}
if ($count == 1) {
push @arr, $rec; }
else {
if ($rec-1 != $arr[-1]) {
print "$arr[0]-$arr[-1]\n";
@arr=();
push @arr, $rec;
$count=1; }
else {
push @arr, $rec; }
}
}
__DATA__
1
2
3
4
5
6
7
12
13
14
15