3

I have 2000+ raster files and counting their statistics. For now I am exporting all to Excel, but to work on it, I need better segregation.

My output:

Name1
1  123
2  243
3  455
Name2
1  432
3  655
4  234
Name3
2  344
3  345...

I have 4 possibilities: 1, 2, 3 and 4, but not all rasters have all combinations. I would like to use awk to create output like that:

name   1    2    3    4
Name1  123  243  455    
Name2  432       655  234
Name3       344  345

So I was trying with this:

for red in {43..64}
do
for nir in {65..193}
do
r.stats -cnl 'gr_r'$red'_n'$nir | \
awk '$1 == 1 {print($2)}' ...

And how to create different rows?

closed as off-topic by Jochen Schwarze, Vince, whyzar, Mark Ireland, nmtoken Jan 23 at 11:52

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions relating to general IT or with no clear GIS component, are off-topic here but can be researched/asked at Stack Overflow (software development), Super User (computing hardware and software), Database Administrators (relational databases) and other SE sites" – Jochen Schwarze, Vince, whyzar, Mark Ireland, nmtoken
If this question can be reworded to fit the rules in the help center, please edit the question.

  • This isn't a GIS or grass specific question and belongs on stackoverflow or unix.stackexchange.com - and by 'belongs' there I think you'll get better answers there, not that I see anything wrong with the answer from @Tomasz. – mankoff Jan 20 at 7:09
1

Assuming the names are not in the form of two numbers, you can pipe to this:

perl -wlne'BEGIN {$,="\t"; @a=qw(name 1 2 3 4)}
if (/^(\d+)\s+(\d+)$/) {$a[$1]=$2;}
else {print @a if @a; @a=(); $a[0]=$_} END{print @a if @a}'

Don't worry about the warnings, the output won't contain them when you redirect it to a file. They're about empty array items. You can silence them by removing the w option, ie. call Perl with

perl -lne

So the whole loop would be:

for f in gr_r{43..64}_n{65..193}; do
    r.stats -cnl "$f"
done | perl -wlne'BEGIN {$,="\t"; @a=qw(name 1 2 3 4)}
    if (/^(\d+)\s+(\d+)$/) {$a[$1]=$2;}
    else {print @a if @a; @a=(); $a[0]=$_} END{print @a if @a}'

As above, it's better to pipe the whole loop to a single Perl process rather than calling it for every r.stats instance. It would be better to also call r.stats just once if possible.

You can redirect the result to a file as usual, that is using the > redirection. So here's the whole bunch:

for f in gr_r{43..64}_n{65..193}; do
    r.stats -cnl "$f"
done | >output.file perl -wlne'BEGIN {$,="\t"; @a=qw(name 1 2 3 4)}
    if (/^(\d+)\s+(\d+)$/) {$a[$1]=$2;}
    else {print @a if @a; @a=(); $a[0]=$_} END{print @a if @a}'

Not the answer you're looking for? Browse other questions tagged or ask your own question.