0

I have a data file looks like :

1 1 1 1 1 1 1 1 2 2 2 2 3 3 3 3 3 3 
2 4 5 8 9 10 13 17 19 29 30 32 33 50 700 800 900 950 

first I want to insert space among each 3 identical values keeping each three identical numbers together in one colum by looking at the first row :

1 1 1  1 1 1  1 1  2 2 2  2  3 3 3  3 3 3 
2 4 5  8 9 10  13 17  19 29 30  32  33 50 700  800 900 950

and then I want to subtract the first value from the last one within each new column at second row ( but if there was only one value at a specific column(here the forth column at second row), then the last value from the previous column should be subtracted from that value(32-30)) while keeping one unique number out of each column from the first row. so the final data should be like this:

1 1 1 2 2 3 3
3 2 4 11 2 667 150 

any suggestion please? meanwhile I should mention my real data is indeed huge and I want to group each 5 unique values at first row. I may want to change the size of group . So I need the script to be flexible ..

2
  • Tried anything ?
    – 123
    Jan 29, 2016 at 14:02
  • 1
    I read your requirements about 10 times before I understood them. (Perl is definitely the tool for this, by the way.)
    – Wildcard
    Jan 29, 2016 at 14:49

2 Answers 2

4

Perl to the rescue!

#!/usr/bin/perl
use warnings;
use strict;

my $group_size = 3;

my @first = split ' ', <>;

my @groups;
my $start_index = 0;
while ($start_index < @first) {
    my $step = 1;
    while ( $step < $group_size
            && $start_index + $step < @first
            && $first[$start_index] == $first[ $start_index + $step ]
          ) {
        ++$step;
    }
    push @groups, $step;
    print $first[$start_index], ' ';
    $start_index += $step;
}
print "\n";

my @numbers = split ' ', <>;

my $last;
for my $size (@groups) {
    my @group = splice @numbers, 0, $size;
    my $value = $group[-1] - $group[0];
    $value = $group[0] - $last if 1 == $size;
    $last = $group[-1];
    print $value, ' ';
}
print "\n";

You haven't specified what should happen if the very first group has just one member.

7
  • choroba that wonts happen.
    – zara
    Jan 29, 2016 at 16:36
  • @zara: Just specify the data file name as the parameter of the program.
    – choroba
    Jan 29, 2016 at 16:51
  • 1
    @zara: T.I.T.S. = Try It To See.
    – choroba
    Jan 29, 2016 at 16:52
  • should I do like this to make it run? ../yourscript.pl data.txt
    – zara
    Jan 29, 2016 at 16:55
  • @zara: If you first make the script executable by chmod u+x program.pl, then yes
    – choroba
    Jan 29, 2016 at 16:55
1

This is similar to choroba's answer

$ cat file
1 1 1 1 1 1 1 1 2 2 2 2 3 3 3 3 3 3 
2 4 5 8 9 10 13 17 19 29 30 32 33 50 700 800 900 950 

$ perl -ane '
    if ($. == 1) {
        for (($n,$i,$j) = (1,0,0); $j < @F; $n++, $j++) {
            if ($n == 3 || $F[$j] != $F[$j+1]) {
                $i-- if $i == $j;
                push @pairs, [$i, $j];
                $n = 0;
                $i = $j + 1;
            }
        }
        printf "%d ", $F[ $_->[1] ] for @pairs;
    }
    else {
        printf "%d ", $F[ $_->[1] ] - $F[ $_->[0] ] for @pairs;
    }
    print "\n";
' < file
1 1 1 2 2 3 3 
3 2 4 11 2 667 150 

For the first line of input ($. == 1) it calculates the list of pairs of indices you are interested in. This works out to:

[[0, 2], [3, 5], [6, 7], [8, 10], [10, 11], [12, 14], [15, 17]]
10
  • does your script works in case if I want to change the group size from 3 into 20?
    – zara
    Jan 29, 2016 at 22:09
  • meanwhile my real data is huge and I need to specify input file in a seperate file than script . how it is possible by your script?
    – zara
    Jan 29, 2016 at 22:10
  • first comment: change $n == 3 to $n == 20. second comment: I don't understand what you're saying -- possibly you want to change < file to < the_real_name_of_your_input_file Jan 29, 2016 at 22:31
  • i mean how should i run this? should i do like: perl yourscript.pl input.txt > out.txt ?
    – zara
    Jan 29, 2016 at 22:34
  • I do not know how to run I copied exactly what you wrote in script in to a .plfile and i tried to run.. but wont work :(
    – zara
    Jan 29, 2016 at 22:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .