Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Distribution: Linux(Redhat,fedora,suse,ubantu), Solaris (s8/s9/s10/nevada/open-solaris)
Posts: 303
Rep:
Reading files in shell scripting
Hi,
I am trying to read the fields of a file and manipulate them, record by record.
Lets say using awk :
awk -F":" `{print $1 $2 $3 $4 $5}' TrackMsgFile.0806`
This prints my fields on screen.But I dont want to print these fields while reading the records instead store them in some variable and manipulate them as per my logic.
Does "awk" or some other shell command provides something for this ?
awk -F":" '{print $1,$2,$3,$4,$5}' TrackMsgFile.0806 | while read one two three four five; do
echo "Here's your vars: $one $two $three $four $five"
done
Note the commas separating the output, so the variables aren't all jumbled together in one.
Last edited by GrapefruiTgirl; 10-25-2010 at 06:41 AM.
awk -F":" '{print $1,$2,$3,$4,$5}' TrackMsgFile.0806 | while read one two three four five; do
echo "Here's your vars: $one $two $three $four $five"
done
Note the commas separating the output, so the variables aren't all jumbled together in one.
but the whole operation of awk+while is still iterating the file and processing them as it iterates. Therefore, the while loop really is redundant.
@OP, you might want to define clearly what you want to do. If you want to store your lines in some variable for LATER use, use and array
Code:
awk '{array[++d]=$0}
{
....
# some other processing here.
}
END{
# here , you process your array
for(i=1;i<=d;i++){
print "do something with " array[i]
}
}'
Distribution: Linux(Redhat,fedora,suse,ubantu), Solaris (s8/s9/s10/nevada/open-solaris)
Posts: 303
Original Poster
Rep:
But lets say one record exists like
1::3::5
Here, I have omitted 2, 4 for explanation.
awk -F":" '{print $1,$2,$3,$4,$5}' TrackMsgFile.0806 | while read one two three four five;
3 will be stored for variable two, 5 for three.
Reason:
awk -F":" '{print $1,$2,$3,$4,$5}' TrackMsgFile.0806 , prints
1 3 5 (as 2nd, 4th filed are blank returns space character)
1 3 5 |while read one two three four five, takes
3,5 for variables two and three respectively.
=>
Is there a mechanism to avoid this ?
Likewise if it will show, wrong result for records like
1:2 3: 4:5 (the second filed contains "2 3") as we are separatinf fields using ":" as field separator)
Last edited by barunparichha; 10-25-2010 at 08:33 AM.
awk -F":" '{for (x=1;x<=5;x++){if($x==" "){$x="*"}};print $1,$2,$3,$4,$5}' TrackMsgFile.0806 | while read one two three four five; do
echo "Here's your vars: $one $two $three $four $five"
done
Technically I'd have thought a space character would count as a character to be read into the appropriate variable, but for whatever reason (maybe multiple spaces count as one?) that doesn't happen.
There are mechanisms however, yes. For example, the above will make an "empty" field (a field that is a single space) return a "*" instead. So, you check your returned variables to see if it's a "*" and if so, then you know it was empty. Maybe a "*" is not the best choice of character to use - a better idea would be to return the word "EMPTY" instead. That would be sensible.
Distribution: Linux(Redhat,fedora,suse,ubantu), Solaris (s8/s9/s10/nevada/open-solaris)
Posts: 303
Original Poster
Rep:
Assuming that, we dont use "*" in any of our records, the above code will work.
But it will still fail to parse records embedded with space. 1:2 3: 4:5 (the second field contains "2 3")
awk -F":" '{for (x=1;x<=5;x++){if($x==" "){$x="*"}};print $1,$2,$3,$4,$5}' TrackMsgFile.0806 | while read one two three four five; do
echo "Here's your vars: $one $two $three $four $five"
done
awk -F":" '{for (x=1;x<=5;x++){if($x==" "){$x="*"}};print $1,$2,$3,$4,$5}' TrackMsgFile.0806, returns
1 2 3 4 5
awk -F":" '{for (x=1;x<=5;x++){if($x==" "){$x="*"}};print $1,$2,$3,$4,$5}' TrackMsgFile.0806 | while read one two three four five
is same as 1 2 3 4 5 | while read one two three four five
But since field separator for read command is space " ", the above command takes: two = 2
three =3
So, still we need some modifications.
Last edited by barunparichha; 10-25-2010 at 08:55 AM.
I don't really understand all of what you've written in the above post, especially the part about embedded whitespace; embedded whitespace should be irrelevant going into the awk, because the field separator is ":", not " ".
In the future, please use some formatting in your posts, and code tags ( http://www.phpbb.com/community/faq.php?mode=bbcode#f2r1 ) to show us code and output. Also it would help to show us exactly what your input file contains -- a few example lines would be good.
Now.. If I understand at all post #9, try this:
Code:
IFS=":"
awk -F":" '{OFS=":";for(x=1;x<=5;x++){if($x==" " || $x==""){$x="*"}};print $1,$2,$3,$4,$5}' TrackMsgFile.0806 | while read one two three four five; do
echo "Here's your vars: '$one' '$two' '$three' '$four' '$five'"
done
If the problem you're describing still persists with that modification, you'll have to please re-explain what the problem is.
Note for demonstration purposes, I put single quotes around the outputted variables, to that any whitespace will be obvious.
Last edited by GrapefruiTgirl; 10-26-2010 at 05:07 AM.
Reason: formatting; added check if $x==""
Distribution: Linux(Redhat,fedora,suse,ubantu), Solaris (s8/s9/s10/nevada/open-solaris)
Posts: 303
Original Poster
Rep:
I regret , if u r confused with post #9. There is nothing wrong with awk, but with the code "while read one two three four five". Please consider following example for clarification.
Let's say the input file TrackMsgFile contains a record like:
1:2 3: 4:5
Note, here the second field contains "2 3".
Now if u run the command
Code:
awk -F":" '{print $1,$2,$3,$4,$5}' TrackMsgFile.0806 | while read one two three four five; do
echo "two: $two"
done
Re-read the code in post #10 carefully- what you just executed is not according to that code. IFS is a bash thing, not for use inside the AWK. OFS is for use in AWK.
And, notice I set IFS=":" before running the code.
Last edited by GrapefruiTgirl; 10-25-2010 at 10:03 AM.
awk -F":" '{OFS=":";print $1,$2,$3,$4,$5}' TestFile | while read one two three four five; do echo "two : $two"; done
Returns
two :
two :
two :
two : 8
two :
So using "OFS" and "IFS" will not help. Using array with awk, might help.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.