1834463 Members
2525 Online
110067 Solutions
New Discussion

Scripting help

 
SOLVED
Go to solution
Paul Thomson_2
Super Advisor

Scripting help

Hi

I have a file containing two columns.
Column 1 = text
Column 2 = numbers

I wish to read the file a line at a time and as long as the value of column 1 is the same, add the values of column 2 together.

Col 1 contains hostnames, so as long as the hostname remains the same, add col 2 together.

Im getting a little stuck on the scripting for this.

Thanks
Argh ye land lovers !
10 REPLIES 10
Lolupee
Regular Advisor

Re: Scripting help

Please, this need more expalnation. Col 1 is a text and you cannot add it to col 2 a number. unless col 1 is a string which could be number or text.

Please, shed more light. Do you mean we should apend col 2 to 1 after?
Paul Thomson_2
Super Advisor

Re: Scripting help

Hi
it a flat file containing information such as

column 1 column 2

server1 10
server1 15
server1 20
server1 40
server2 19
server2 19

In this example, I would like to read the file line by line and as long as column 1 is equal to server1 add the numbers from column 2 making a total of 85 in this example. I could then write server1 and the total figure to another file for example.
Argh ye land lovers !
Peter Godron
Honored Contributor

Re: Scripting help

Paul,
no doubt the perl experts are going to produce a one-liner!
However:
#!/usr/bin/sh
oldhost=""
while read host number
do
if [ "$host" = "$oldhost" ]
then
counted=`expr $counted + $number`
else
echo $oldhost $counted
oldhost=$host
counted=$number
fi
done < a.lis

Should work as long as there is one additional empty line at the end of the a.lis input file.
H.Merijn Brand (procura
Honored Contributor

Re: Scripting help

Assuming your colums are separated by white space

# perl -nle'sub z{print"$p:$s";$s=0}($h,$n)=(/^\s*(\S+)\s+(\d+)/);$h eq$p or z;$p=$h;$s+=$n}END{z' file

Demo:

lt09:/home/merijn 101 > cat >xx.txt
a 1
a 4
a 1

b 2
b 2
c 7
d 8
d 0
lt09:/home/merijn 102 > perl -nle'sub z{print"$p:$s";$s=0}($h,$n)=(/^\s*(\S+)\s+(\d+)/);$h eq$p or z;$p=$h;$s+=$n}END{z' xx.txt
:
a:6
:0
b:4
c:7
d:8
lt09:/home/merijn 103 >

Enjoy, Have FUN! H.Merijn


Enjoy, Have FUN! H.Merijn
James R. Ferguson
Acclaimed Contributor

Re: Scripting help

Hi:

# perl -nalF -e '$prev=$F[0] if !defined($prev);if ($F[0] eq $prev) {$i++} else {pr
int "$prev=$i";$i=1};$prev=$F[0];END{print "$prev=$i"}' file

Regards!

...JRF...
Patrick Wallek
Honored Contributor
Solution

Re: Scripting help

It's not PERL, and it's not very pretty, but it works and does not need a blank line at the end.

# cat testscript


#!/usr/bin/sh

ITER=1
NUMTOT=0
while read HOST NUM
do
if [[ ${HOSTB} = ${HOST} || ${ITER} = 1 ]] ; then
((NUMTOT=$NUMTOT+$NUM))
HOSTB=$HOST
ITER=2
else
echo "The total for ${HOSTB} is ${NUMTOT}"
NUMTOT=0
((NUMTOT=$NUMTOT+$NUM))
HOSTB=$HOST
fi
done < testfile
echo "The total for ${HOSTB} is ${NUMTOT}"

Fat Scrape
Honored Contributor

Re: Scripting help

Hi,

#!/opt/perl/bin/perl -w


my %hash = ();

my $file_in = "/tmp/file_in";
my $file_out = "/tmp/file_out";

open (IN, "<$file_in" ) or die "cannot open file $file_in";
open (OUT, ">$file_out") or die "cannot open file $file_out";

while (my $line = ){
chomp($line);
my ($host, $num) = split(/\s+/,$line);
print "$host\n";
$hash{$host}[0] += $num;
}

foreach my $key (sort keys %hash){
print OUT "$key $hash{$key}[0]\n";
}

Regards,
Lolupee
Regular Advisor

Re: Scripting help

Mine cant be better. You already have more than enough.
Paul Thomson_2
Super Advisor

Re: Scripting help

Thanks all, I have many choices to go with now.

Have tested some and they look fine.

Thanks
Argh ye land lovers !
Fat Scrape
Honored Contributor

Re: Scripting help

Hi,

obviously

/tmp/file_in is:

server1 10
server1 15
server1 20
server1 40
server2 19
server2 19

/tmp/file_out is:

server1 85
server2 38

Regards,