LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-01-2012, 03:26 AM   #1
ilukacevic
LQ Newbie
 
Registered: Jul 2010
Posts: 22

Rep: Reputation: 0
Using the for loop in awk


Dear all,

I'm trying to solve the following problem, but without success.

I have a file with a lot of columns and an arbitrary number of rows, like

1 0.4 0.3 0.7 ...
2 0.1 0.4 0.2 ...
.
.
.

I'd like to print a file which would look like this

@target G0.S0
@type xy
1 0.4
2 0.1
.
.
.
@target G0.S1
@type xy
1 0.3
2 0.4
.
.
.
@target G0.S2
@type xy
1 0.7
2 0.2
.
.
.

So, the S0 set should contain the 1st and the 2nd column, S1 set the 1st and the 3rd, S2 set the 1st and the 4th and so on. I've set up a script which uses awk to print a file like the wanted one

#!/bin/sh

awk 'BEGIN {
for (i = 0; i <= 1; i++)
{print "@target G0.S" i
print "@type xy"
print $1,$(i+2)}
}' bands1.dat > columns.dat

where bands1.dat is a file which contains the columns. The execution of the script, however, gives (if I want only 2 rows)

@target G0.S0
@type xy

@target G0.S1
@type xy


i.e. it doesn't print the data columns in between the sets.

Can anyone help me to figure out why this hapens (and possibly solve the problem)?

Thank you in advance.

Igor
 
Old 02-01-2012, 05:04 AM   #2
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
You need a getline after print "@type xy" and before print $1,$(i+2) to read a line and thus assign values to $1 and $2.
 
Old 02-01-2012, 05:24 AM   #3
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

How about
Code:
# slice.awk
{ 
    for (i=1; i<=NF; i++)  {
        a[NR,i] = $i
    }
}
END {
	for(i=2; i<=NF; i++){
		print "@target G0.S" i-2 
		print "@type xy"
		for(j=1; j<=NR; j++) {
			print a[j,1], a[j,i]
		}
	}
}
Code:
$ cat bands.dat 
1 0.4 0.3 0.7
2 0.1 0.4 0.2
3 0.1 0.5 0.2
4 0.1 0.6 0.2
5 0.1 0.6 0.4
$ awk -f slice.awk bands.dat 
@target G0.S0
@type xy
1 0.4
2 0.1
3 0.1
4 0.1
5 0.1
@target G0.S1
@type xy
1 0.3
2 0.4
3 0.5
4 0.6
5 0.6
@target G0.S2
@type xy
1 0.7
2 0.2
3 0.2
4 0.2
5 0.4

Last edited by firstfire; 02-01-2012 at 05:26 AM.
 
Old 02-01-2012, 06:34 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
And another:
Code:
awk '{for(i=2;i<=NF;i++)nums[i-1]=nums[i-1]((nums[i-1])?"\n":"")$1" "$i}END{for(x in nums)print "@target G0.S"x-1"\n@type xy\n"nums[x]}' bands.dat
 
Old 02-15-2012, 06:01 AM   #5
ilukacevic
LQ Newbie
 
Registered: Jul 2010
Posts: 22

Original Poster
Rep: Reputation: 0
Dear catkin, firstfire and grail,

first I'd like to apologize for replying after so many days. Second I'd like to thank you all three for helping me. Here're my comments.

Quote:
Originally Posted by catkin View Post
You need a getline after print "@type xy" and before print $1,$(i+2) to read a line and thus assign values to $1 and $2.
This doesn't work. I get an awk syntax error:

awk: cmd. line:4: getline print $1,$(i+2)}
awk: cmd. line:4: ^ syntax error

Since I'm a novice in awk scripting, I suppose that something else also needs to be inputed in the script in order for it to work this way. I read the meaning of the getline command, but it's still beyond my current knowledge.

Quote:
Originally Posted by firstfire View Post
Hi.

How about...
This one works perfectly. I still have to spend some time to figure how it actually works.

Quote:
Originally Posted by grail View Post
And another:
Code:
awk '{for(i=2;i<=NF;i++)nums[i-1]=nums[i-1]((nums[i-1])?"\n":"")$1" "$i}END{for(x in nums)print "@target G0.S"x-1"\n@type xy\n"nums[x]}' bands.dat
This one works, but the 1st set starts with @target G0.S9 and not @target G0.S0, as I'd like it to. I have to spend some time here, also, in order to figure out what went amiss.

All in all, you have been very helpful; I'll mark this subject as solved, although I still do not understand why my initial script doesn't work, i.e. why doesn't it print the columns.

Yours,

Igor L.
 
Old 02-15-2012, 09:32 AM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
The getline options that catkin refers to will need a semi-colon after them, ie. getline; print $1,$(i+2)

As for mine not starting at the correct number ... the 'for(x in nums)' is not ordered so if you simply change this to a standard for loop starting at 1 and for the length of nums, it should be ok
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] using for loop in awk ilukacevic Programming 6 03-29-2011 02:48 PM
How to use awk in a for loop? cliffyao Programming 2 10-27-2010 10:51 PM
[SOLVED] awk for-loop babaqga Linux - Software 4 09-02-2010 03:57 AM
for loop in awk command jssidhu4 Programming 7 03-31-2010 04:19 AM
awk in loop How to Nkunzis Linux - Newbie 3 12-10-2006 01:34 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration