Unix Shell - read and process a file each 3 lines

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > August 2007 > read and process a file each 3 lines





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author read and process a file each 3 lines
gniagnia

2007-08-23, 1:27 pm

Hi all !

Ok here is the kind of file i need to deal with :

value 2
column 7
line 1
value 3
column 3
line 8
value 3
column 4
line 1
value 2
column 7
line 8
value 8
column 6
line 10

etc...


I need to create a bi-dimensional array (10 lines over 14 columns) and
fill it with the values above.
For instance, value "2" should be recorded in "line 1 / column 7" of
my array, value "3" in "line 8 / column 3", etc....
And any empty element of this array should be filled with the value
"-1"...

In the end, this array should print like this :

-1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1

I guess I need to find a loop that will process the file each 3
lines...I don't have any idea on how to do this....
thank you in advance for your help

regards

Edward Rosten

2007-08-23, 7:21 pm

On Aug 23, 12:14 pm, gniagnia <gniag...@gmail.com> wrote:
> Hi all !
>
> Ok here is the kind of file i need to deal with :
>
> value 2
> column 7
> line 1


[snip]

>
> I need to create a bi-dimensional array (10 lines over 14 columns) and
> fill it with the values above.


In AWK, the file as record based where "value" is the record
seperator. Then insert the data in to a certain row,col of an array.
Finally loop over rows and columns printing out the contents, or -1 if
a cell is empty.

BEGIN{RS="value"}

{
data[$5, $3] = $1
}

END{
for(l=1; l <= 10; l++)
for(c=1; c <= 14; c++)
{
if( (l SUBSEP c) in data)
printf data[l,c]
else
printf "-1"

printf (c==14?"\n":";")
}
}


-Ed

Cyrus Kriticos

2007-08-23, 7:21 pm

gniagnia wrote:
> Hi all !
>
> Ok here is the kind of file i need to deal with :
>
> value 2
> column 7
> line 1
> [...]
> etc...
>
>
> I need to create a bi-dimensional array (10 lines over 14 columns) and
> fill it with the values above.
> [...]
> In the end, this array should print like this :
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1
> [...]


#!/bin/bash

COL=14
ROW=10
FILE="matrix.dat"

init_matrix ()
{
for ((i=0; i<$COL*$ROW; i++)); do m[$i]=-1; done
}

dump_matrix ()
{
for ((i=0; i<$ROW; i++)); do
for ((j=0; j<$COL; j++)); do
let pos=${i}*${COL}+${j}
echo -n "${m[$pos]};"
done
echo
done
}

fill_matrix ()
{
while read value; do
read column
read line
let pos=(${line#* }-1)*${COL}+${column#* }-1
m[$pos]=${value#* }
done < $FILE
}

init_matrix
fill_matrix
dump_matrix | sed "s/;$//"

--
Best | "Was bekommt man/frau, wenn man/frau Software kauft?
regards | Nichts außer einem Haufen Nullen und Einsen."
Cyrus | -- aus d. Lizenzvereinbarung von Spybot Search&Destroy
Cyrus Kriticos

2007-08-23, 7:21 pm

gniagnia wrote:
> Hi all !
>
> Ok here is the kind of file i need to deal with :
>
> value 2
> column 7
> line 1
> [...]
> etc...
>
>
> I need to create a bi-dimensional array (10 lines over 14 columns) and
> fill it with the values above.
> [...]
> In the end, this array should print like this :
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1
> [...]


#!/bin/bash

COL=14
ROW=10
FILE="matrix.dat"

init_matrix ()
{
for ((i=0; i<$COL*$ROW; i++)); do m[$i]=-1; done
}

fill_matrix ()
{
while read x value; do
read x column
read x line
let pos=(${line}-1)*${COL}+${column}-1
m[$pos]=${value}
done < $FILE
}

dump_matrix ()
{
for ((i=0; i<$ROW; i++)); do
for ((j=0; j<$COL; j++)); do
let pos=${i}*${COL}+${j}
echo -n "${m[$pos]};"
done
echo
done
}

init_matrix
fill_matrix
dump_matrix | sed "s/;$//"

--
Best | "Was bekommt man/frau, wenn man/frau Software kauft?
regards | Nichts außer einem Haufen Nullen und Einsen."
Cyrus | -- aus d. Lizenzvereinbarung von Spybot Search&Destroy
Cyrus Kriticos

2007-08-23, 7:21 pm

gniagnia wrote:
> Hi all !
>
> Ok here is the kind of file i need to deal with :
>
> value 2
> column 7
> line 1
> [...]
> etc...
>
>
> I need to create a bi-dimensional array (10 lines over 14 columns) and
> fill it with the values above.
> [...]
> In the end, this array should print like this :
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1
> [...]


#!/bin/bash

COL=14
ROW=10
FILE="matrix.dat"

init_matrix ()
{
for ((i=0; i<$COL*$ROW; i++)); do m[$i]=-1; done
}

fill_matrix ()
{
while read x value; do
read x column
read x line
let pos=(${line}-1)*${COL}+${column}-1
m[$pos]=${value}
done < $FILE
}

dump_matrix ()
{
for ((i=0; i<$ROW; i++)); do
for ((j=0; j<$COL; j++)); do
let pos=${i}*${COL}+${j}
line="${line}${m[$pos]};"
done
echo "${line%;}"
line=""
done
}

init_matrix
fill_matrix
dump_matrix

--
Best | "Was bekommt man/frau, wenn man/frau Software kauft?
regards | Nichts außer einem Haufen Nullen und Einsen."
Cyrus | -- aus d. Lizenzvereinbarung von Spybot Search&Destroy
Cyrus Kriticos

2007-08-23, 7:21 pm

gniagnia wrote:
> Hi all !
>
> Ok here is the kind of file i need to deal with :
>
> value 2
> column 7
> line 1
> [...]
> etc...
>
>
> I need to create a bi-dimensional array (10 lines over 14 columns) and
> fill it with the values above.
> [...]
> In the end, this array should print like this :
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1
> [...]


#!/bin/bash

COL=14
ROW=10
FILE="matrix.dat"

init_matrix ()
{
for ((i=0; i<$COL*$ROW; i++)); do m[$i]=-1; done
}

fill_matrix ()
{
while read x value; do
read x column
read x line
let pos=(${line}-1)*${COL}+${column}-1
m[$pos]=${value}
done < $FILE
}

dump_matrix ()
{
for ((i=0; i<$ROW; i++)); do
for ((j=0; j<$COL; j++)); do
let pos=${i}*${COL}+${j}
l="${l}${m[$pos]};"
done
echo "${l%;}"
l=""
done
}

init_matrix
fill_matrix
dump_matrix


--
Best | "Was bekommt man/frau, wenn man/frau Software kauft?
regards | Nichts außer einem Haufen Nullen und Einsen."
Cyrus | -- aus d. Lizenzvereinbarung von Spybot Search&Destroy
Janis

2007-08-23, 7:21 pm

On 23 Aug., 22:30, Edward Rosten <Edward.Ros...@gmail.com> wrote:
>
> if( (l SUBSEP c) in data)


if ( (l,c) in data)

....is easier to read.

Janis

gniagnia

2007-08-24, 7:23 am

On 23 ao=FBt, 23:43, Janis <janis_papanag...@hotmail.com> wrote:
> On 23 Aug., 22:30, Edward Rosten <Edward.Ros...@gmail.com> wrote:
>
>
>
>
> if ( (l,c) in data)
>
> ...is easier to read.
>
> Janis



The awk solution might be shorter, Cyrus's one is way easier to read
for me (and it works perfectly!)
I don't understand the line :

data[$5, $3] =3D $1

..=2E.and couldn't make it work either. (I really need to practise awk
more)


Thanks again !
regards

Ed Morton

2007-08-24, 1:24 pm

Edward Rosten wrote:

> On Aug 23, 12:14 pm, gniagnia <gniag...@gmail.com> wrote:
>
>
>
> [snip]
>
>
>
>
> In AWK, the file as record based where "value" is the record
> seperator. Then insert the data in to a certain row,col of an array.
> Finally loop over rows and columns printing out the contents, or -1 if
> a cell is empty.
>
> BEGIN{RS="value"}
>
> {
> data[$5, $3] = $1
> }
>
> END{
> for(l=1; l <= 10; l++)
> for(c=1; c <= 14; c++)
> {
> if( (l SUBSEP c) in data)
> printf data[l,c]
> else
> printf "-1"


printf takes a formatting string as it's first argument, then the data
to be printed:

printf "%s",((1,c) in data ? data[l,c] : "-1")

> printf (c==14?"\n":";")


printf "%s",(c==14?"\n":";")
> }
> }
>
>
> -Ed
>

Ed Morton

2007-08-24, 1:24 pm

gniagnia wrote:

> On 23 août, 23:43, Janis <janis_papanag...@hotmail.com> wrote:
>
>
>
>
> The awk solution might be shorter, Cyrus's one is way easier to read


Maybe that's because it was posted 4 times ;-).

> for me (and it works perfectly!)
> I don't understand the line :
>
> data[$5, $3] = $1


You said "I need to create a bi-dimensional array". That's what the
above does.

> ...and couldn't make it work either.


In what way couldn't you make it work?

(I really need to practise awk
> more)


Yes. For text processing problems like this, awk/perl/ruby are the right
tools to use, not a shell script. Here's a slightly simpler awk script:

awk '
NR%3==1{ v=$2 }
NR%3==2{ c=$2; C=(c > C ? c : C) }
NR%3==0{ l=$2; data[l,c]=v; L=( l > L ? l : L) }
END {
for(l=1; l<=L; l++)
for(c=1; c<=C; c++)
printf "%s%s",(((l,c) in data)?data[l,c]:"-1"), (c==C?"\n":";")
}
' file

Rather than hard-coding the 10 and 14, I'm just figuring out the size (C
and L) from your input data. Obviously you can hard-code it if you prefer.

Hopefully that'll help.

Ed.
gniagnia

2007-08-24, 1:24 pm

> awk '
> NR%3==1{ v=$2 }
> NR%3==2{ c=$2; C=(c > C ? c : C) }
> NR%3==0{ l=$2; data[l,c]=v; L=( l > L ? l : L) }
> END {
> for(l=1; l<=L; l++)
> for(c=1; c<=C; c++)
> printf "%s%s",(((l,c) in data)?data[l,c]:"-1"), (c==C?"\n":";")}
>
> ' file
>
> Rather than hard-coding the 10 and 14, I'm just figuring out the size (C
> and L) from your input data. Obviously you can hard-code it if you prefer.
>
> Hopefully that'll help.
>
> Ed.


Your last script fulfils my need perfectly because the size of the
array might vary in the future.
I still got to understand it (espcecially those "NR%3..." lines)
am gonna buy a "awk for dummies" soon

thanks again!




Bill Marcum

2007-08-24, 1:24 pm

On Fri, 24 Aug 2007 09:08:41 -0700, gniagnia
<gniagnia@gmail.com> wrote:
>
>
> Your last script fulfils my need perfectly because the size of the
> array might vary in the future.
> I still got to understand it (espcecially those "NR%3..." lines)
> am gonna buy a "awk for dummies" soon
>
> thanks again!
>

"%" is the modulo operator (A%B is the remainder of A/B).


--
Got a complaint about the Internal Revenue Service?
Call the convenient toll-free "IRS Taxpayer Complaint Hot Line Number":
1-800-AUDITME
John W. Krahn

2007-08-25, 1:22 pm

gniagnia wrote:
>
> Ok here is the kind of file i need to deal with :
>
> value 2
> column 7
> line 1
> value 3
> column 3
> line 8
> value 3
> column 4
> line 1
> value 2
> column 7
> line 8
> value 8
> column 6
> line 10
>
> etc...
>
>
> I need to create a bi-dimensional array (10 lines over 14 columns) and
> fill it with the values above.
> For instance, value "2" should be recorded in "line 1 / column 7" of
> my array, value "3" in "line 8 / column 3", etc....
> And any empty element of this array should be filled with the value
> "-1"...
>
> In the end, this array should print like this :
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1


$ echo "value 2
column 7
line 1
value 3
column 3
line 8
value 3
column 4
line 1
value 2
column 7
line 8
value 8
column 6
line 10" | PERL -lne'
BEGIN { @x = map [ map -1, 1 .. 14 ], 1 .. 10 }

$lin = $1 if /^line\D+(\d+)/;
$col = $1 if /^column\D+(\d+)/;
$val = $1 if /^value\D+(\d+)/;

if ( defined $lin && defined $col && defined $val ) {
$x[ $lin - 1 ][ $col - 1 ] = $val;
$lin = $col = $val = undef;
}

END { print join ";", @$_ for @x }
'
-1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1




John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
William James

2007-08-25, 7:19 pm

On Aug 23, 1:14 pm, gniagnia <gniag...@gmail.com> wrote:
> Hi all !
>
> Ok here is the kind of file i need to deal with :
>
> value 2
> column 7
> line 1
> value 3
> column 3
> line 8
> value 3
> column 4
> line 1
> value 2
> column 7
> line 8
> value 8
> column 6
> line 10
>
> etc...
>
> I need to create a bi-dimensional array (10 lines over 14 columns) and
> fill it with the values above.
> For instance, value "2" should be recorded in "line 1 / column 7" of
> my array, value "3" in "line 8 / column 3", etc....
> And any empty element of this array should be filled with the value
> "-1"...
>
> In the end, this array should print like this :
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1


#!ruby
require 'enumerator'

# Make a 1-dimensional array of all the file's numbers.
numbers = ARGF.map{|s| s[ /\d+/ ].to_i }

# Arrange in groups of 3.
records = numbers.enum_slice(3).to_a

# Determine number of lines needed in output array.
lines = records.map{|a| a[2] }.max
# Determine number of columns needed in output array.
columns = records.map{|a| a[1] }.max

# Make 2-dimensional array
array = []
lines.times{ array << [-1] * columns }

# Put values in array.
records.each{|v,c,l| array[l-1][c-1] = v }

# Print result.
array.each{|line| puts line.join(";") }

=====

The array "numbers" looks like
[2, 7, 1, 3, 3, 8, 3, 4, 1, 2, 7, 8, 8, 6, 10]

And the array "records" is
[[2, 7, 1], [3, 3, 8], [3, 4, 1], [2, 7, 8], [8, 6, 10]]

The output is
-1;-1;-1;3;-1;-1;2
-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1
-1;-1;3;-1;-1;-1;2
-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;8;-1

Janis

2007-08-27, 7:23 am

On 24 Aug., 11:21, gniagnia <gniag...@gmail.com> wrote:
> On 23 ao=FBt, 23:43, Janis <janis_papanag...@hotmail.com> wrote:
>
>
>
>
>
>
> The awk solution might be shorter, Cyrus's one is way easier to read
> for me (and it works perfectly!)


I didn't say it wouldn't work, and it's not for the shortness.
The tupel syntax resembles the array indexing better.

> I don't understand the line :
>
> data[$5, $3] =3D $1


data[$5 SUBSEP $3] =3D $1

May be easier to understand and easier read for you?

Janis

>
> ...and couldn't make it work either. (I really need to practise awk
> more)
>
> Thanks again !
> regards



gniagnia

2007-08-29, 7:17 am

> data[$5 SUBSEP $3] = $1
>
> May be easier to understand and easier read for you?
>
> Janis



Yes indeed

But I have another question to ask ...

I am trying to write a second script, in perl, that would print the
above-mentionned array, and then reckon each value encountered in my
array.

The output would be the following :




-1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
-1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1


-> Value "3" found "2" times in the array
-> Value "2 found "2" time in the array
-> Value "8 found "1" time in the array

etc...



So far, I succeeded to print that array via PERL (which i am really
proud of ) :


my $map_file=/home/test/array.txt

open(FD, $map_file) or die "$map_file : $!";
@map_lines=<FD>;
close(FD);

foreach my $i (0..$#map_lines)
{
my @res=split(";", $map_lines[$i]);
foreach my $j (0..$#res)
{
print $res[$j]
}
}


But I don't have the slighest idea on how to script the couting
part...




Edward Rosten

2007-08-29, 1:20 pm

On Aug 24, 8:31 am, Ed Morton <mor...@lsupcaemnt.com> wrote:

> printf takes a formatting string as it's first argument, then the data
> to be printed:


> printf (c==14?"\n":";")


> printf "%s",(c==14?"\n":";")


The format string contains literal text as well as formatting for
arguments.. Since the data is either a \n or a ;, it can never be
misinterpreted as a format string, so the first form is OK.

-Ed

Ed Morton

2007-08-29, 7:26 pm

Edward Rosten wrote:
> On Aug 24, 8:31 am, Ed Morton <mor...@lsupcaemnt.com> wrote:
>
>
>
>
>
>
>
>
> The format string contains literal text as well as formatting for
> arguments.. Since the data is either a \n or a ;, it can never be
> misinterpreted as a format string, so the first form is OK.


I agree in the cases above, but those aren't the lines I was refering
to. What I actually said was:

>
> printf takes a formatting string as it's first argument, then the data to be printed:
>
> printf "%s",((1,c) in data ? data[l,c] : "-1")


so I was effectively contrasting these:

printf data[l,c]

printf "%s",data[l,c]

in which case since you're referencing data[l,c] which was populated
from your input file, you must use the second format.

Ed.
Glenn Jackman

2007-08-29, 7:26 pm

At 2007-08-29 08:05AM, "gniagnia" wrote:
> But I have another question to ask ...
>
> I am trying to write a second script, in perl, that would print the
> above-mentionned array, and then reckon each value encountered in my
> array.
>
> The output would be the following :
>
>
>
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1
>
>
> -> Value "3" found "2" times in the array
> -> Value "2 found "2" time in the array
> -> Value "8 found "1" time in the array
>
> etc...
>
>
>
> So far, I succeeded to print that array via PERL (which i am really
> proud of ) :
>
>
> my $map_file=/home/test/array.txt
>
> open(FD, $map_file) or die "$map_file : $!";
> @map_lines=<FD>;
> close(FD);
>
> foreach my $i (0..$#map_lines)
> {
> my @res=split(";", $map_lines[$i]);
> foreach my $j (0..$#res)
> {
> print $res[$j]
> }
> }
>
>
> But I don't have the slighest idea on how to script the couting
> part...


This isn't a PERL group, but nevertheless, some comments:

- you don't have to read the whole file into memory
- the first argument to split is usually a regular expression.
- for counting a set of discrete things, a hash would be the best
approach.

So:
open my $fd, '<', $map_file or die "$map_file : $!";
my %count;
while (<$fd> ) {
chomp;
foreach my $element (split /;/) {
$count{$element}++;
}
}
close $fd;
delete $count{-1}; # since you don't care about "-1"
# the following sorts by number of times found, decreasing
foreach my $n (sort {$count{$a} <=> $count{$b}} keys %count) {
print qq{value "$n" found "$count{$n}" times\n};
}


--
Glenn Jackman
"You can only be young once. But you can always be immature." -- Dave Barry
Cyrus Kriticos

2007-08-29, 7:26 pm

Glenn Jackman wrote:
> At 2007-08-29 08:05AM, "gniagnia" wrote:
>
> This isn't a PERL group, but nevertheless, some comments:
>
> - you don't have to read the whole file into memory
> - the first argument to split is usually a regular expression.
> - for counting a set of discrete things, a hash would be the best
> approach.
>
> So:
> open my $fd, '<', $map_file or die "$map_file : $!";
> my %count;
> while (<$fd> ) {
> chomp;
> foreach my $element (split /;/) {
> $count{$element}++;
> }
> }
> close $fd;
> delete $count{-1}; # since you don't care about "-1"
> # the following sorts by number of times found, decreasing
> foreach my $n (sort {$count{$a} <=> $count{$b}} keys %count) {
> print qq{value "$n" found "$count{$n}" times\n};
> }
>


or

your-script.pl | tr ";" "\n" | sort | uniq -c | awk '{print "Value \"" $2
"\" found \"" $1 "\" times in the array"}'

--
Best regards | "The only way to really learn scripting is to write
Cyrus | scripts." -- Advanced Bash-Scripting Guide
Glenn Jackman

2007-08-29, 7:26 pm

At 2007-08-29 04:03PM, "Cyrus Kriticos" wrote:
> Glenn Jackman wrote:
>
> or
>
> your-script.pl | tr ";" "\n" | sort | uniq -c | awk '{print "Value \"" $2
> "\" found \"" $1 "\" times in the array"}'


or do more in awk

tr ';' '\n' < numbers.txt | awk '
$1 == "-1" {next}
{count[$1]++}
END {
for (n in count) {
printf("value \"%d\" found \"%d\" times\n", n,count[n])
}
}'


--
Glenn Jackman
"You can only be young once. But you can always be immature." -- Dave Barry
John W. Krahn

2007-08-30, 1:19 am

gniagnia wrote:
>
> I am trying to write a second script, in perl, that would print the
> above-mentionned array, and then reckon each value encountered in my
> array.
>
> The output would be the following :
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1
>
>
> -> Value "3" found "2" times in the array
> -> Value "2 found "2" time in the array
> -> Value "8 found "1" time in the array
>
> etc...
>
> So far, I succeeded to print that array via PERL (which i am really
> proud of ) :
>
>
> my $map_file=/home/test/array.txt
>
> open(FD, $map_file) or die "$map_file : $!";
> @map_lines=<FD>;
> close(FD);
>
> foreach my $i (0..$#map_lines)
> {
> my @res=split(";", $map_lines[$i]);
> foreach my $j (0..$#res)
> {
> print $res[$j]
> }
> }
>
>
> But I don't have the slighest idea on how to script the couting
> part...


my $map_file = '/home/test/array.txt';

open FD, '<', $map_file or die "$map_file : $!";

my %counts;
while ( <FD> ) {
chomp;
$_ >= 0 and $counts{ $_ }++ for split /;/;
}

for my $key ( keys %counts ) {
print qq[Value "$key" found "$counts{$key}" time],
$counts{$key} == 1 ? "" : "s",
"in the array\n";
}



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
mik3l3374@gmail.com

2007-08-30, 7:20 am

On Aug 24, 2:14 am, gniagnia <gniag...@gmail.com> wrote:
> Hi all !
>
> Ok here is the kind of file i need to deal with :
>
> value 2
> column 7
> line 1
> value 3
> column 3
> line 8
> value 3
> column 4
> line 1
> value 2
> column 7
> line 8
> value 8
> column 6
> line 10
>
> etc...
>
> I need to create a bi-dimensional array (10 lines over 14 columns) and
> fill it with the values above.
> For instance, value "2" should be recorded in "line 1 / column 7" of
> my array, value "3" in "line 8 / column 3", etc....
> And any empty element of this array should be filled with the value
> "-1"...
>
> In the end, this array should print like this :
>
> -1;-1;-1;3;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;3;-1;-1;-1;2;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1
> -1;-1;-1;-1;-1;8;-1;-1;-1;-1;-1;-1;-1;-1
>
> I guess I need to find a loop that will process the file each 3
> lines...I don't have any idea on how to do this....
> thank you in advance for your help
>
> regards


if you can have Python as an alternative:
arr = [[-1]*14 for i in range(10)]
val=[]
row=[]
col=[]
for line in open("file"):
number=line.split()[-1]
if line.startswith("value"):
val.append(int(number))
elif line.startswith("column"):
col.append(int(number))
elif line.startswith("line"):
row.append(int(number))
for item in zip(row,col,val):
arr[item[0]-1][item[1]-1]=item[2]
for i in arr:
print i

output:

[-1, -1, -1, 3, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, 3, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[-1, -1, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1]

Edward Rosten

2007-08-30, 1:20 pm

On Aug 29, 12:42 pm, Ed Morton <mor...@lsupcaemnt.com> wrote:

> so I was effectively contrasting these:
>
> printf data[l,c]
>
> printf "%s",data[l,c]
>
> in which case since you're referencing data[l,c] which was populated
> from your input file, you must use the second format.


Good point. I was assuming, rather unsafely, that the input data was
numeric.

-Ed


Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2009 webservertalk.com