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 |
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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
|
 |
|
07-15-2005, 11:29 AM
|
#1
|
Member
Registered: Aug 2003
Posts: 39
Rep:
|
bash; reading values from a file
A text file has lines containing three fields; tag, description, status.
Example:
Tag Description Status
tag1 this is tag1 good <--- file contents
tag2 this is tag2 bad <---
If I use 'read' in a bash script as in following example the variable 'desc' only gets the first
word in the description. Variable 'status' gets the second word in the description:
Example:
read tag desc status
echo $tag ---> tag1
echo $desc ---> this
echo $status ---> is
How can read the full description into variable 'desc'? (desciption has variable number of words)
To say it another way, is there any way to read columns of information instead of individual fields of information? Can I combine 'cut' with 'read' somehow? Is there a way to do formatted input?
xyz
|
|
|
07-15-2005, 11:32 AM
|
#2
|
LQ Newbie
Registered: Jul 2005
Posts: 9
Rep:
|
have you tried to type "tag1 this is" with the quotes as the input?
|
|
|
07-15-2005, 01:34 PM
|
#3
|
Member
Registered: Jan 2005
Distribution: Archlinux, Debian, Centos
Posts: 222
Rep:
|
You better define some splitting characters for your input. It seems that your description can be multiple words with white-space separation. When you say something like:
tag1;description; blurb
You may just make a
Code:
read line
tag=echo $line | cut -d; -f1
descr=echo $line | cut -d; -f2
etc.
|
|
|
07-15-2005, 03:22 PM
|
#4
|
Member
Registered: Aug 2003
Posts: 39
Original Poster
Rep:
|
Thank's guys. I'm not at a point where it can test your solutions at the moment but I see where you're going and it looks good. I'll try it soon. Most of all I appreciate your consideration. Thanks again.
|
|
|
07-16-2005, 10:37 AM
|
#5
|
Member
Registered: May 2005
Posts: 378
Rep:
|
If your status is always a single word, it'd be much easier to parse it as "tag status description". I've always found that if you "read" into a list of shell variables, the last one gets the rest of the line if there are more words than variables. That's in ksh (not pdksh which is an abomination), I'm not sure if bash does it this way (I could try it, but it's your problem, not mine!).
It's just occurred to me that you could use awk to read the last word of a line and reformat the data to suit your processing:
Code:
awk '{print $NF}' somefile
Last edited by eddiebaby1023; 07-16-2005 at 10:39 AM.
|
|
|
07-21-2005, 12:31 PM
|
#6
|
Member
Registered: Aug 2003
Posts: 39
Original Poster
Rep:
|
traene,
Your solution is nearly ideal. It would be perfect if not for an inherent property of the "read" command. Unfortunately 'read' strips spaces from the beginning of the line. Since the file I'm reading doesn't include delimiters I need to split the columns based on position. The "cut" command will do that (cut -c1-3). But because "read" strips spaces at the beginning of the line the columns are not in consistent positions.
For example. Say the following two lines of text are in the input file.
" 1 23"
" 12 34"
Using 'read aline', columns in $aline become shifted as follows:
"1 23"
"12 34"
Shifting the columns makes 'cut' useless.
A way to read a line literally from a file without stripping the initial spaces is needed.
Any ideas?
thanks
Quote:
Originally posted by traene
You better define some splitting characters for your input. It seems that your description can be multiple words with white-space separation. When you say something like:
tag1;description; blurb
You may just make a
Code:
read line
tag=echo $line | cut -d; -f1
descr=echo $line | cut -d; -f2
etc.
|
|
|
|
07-21-2005, 02:48 PM
|
#7
|
LQ Guru
Registered: Mar 2004
Distribution: Slackware
Posts: 6,797
|
From your example : " 1 23"
You mean 1 is in second column and 23 in the third ?
|
|
|
07-22-2005, 07:08 AM
|
#8
|
Member
Registered: Aug 2003
Posts: 39
Original Poster
Rep:
|
Quote:
Originally posted by keefaz
From your example : " 1 23"
You mean 1 is in second column and 23 in the third ?
|
Well, I was trying to show that lines beginning with spaces will be altered by the "read" command. That is, leading spaces will be removed. Therefore, if you're trying to cut columns of information out of the line based on character position then you can't do it because removing the leading spaces shifts the columns to the left by an amount equal to the number of spaces removed.
To say it another way, there appears to be no way to read a line of text into a shell script unaltered if any the line begin with spaces. The leading spaces will be removed by "read".
To say it yet again, there appears to be no way to read a text file into a shell script and write it out to another file so that the two files are identical, if the original file contains a space at the beginning of a line.
|
|
|
07-22-2005, 07:41 AM
|
#9
|
LQ Guru
Registered: Mar 2004
Distribution: Slackware
Posts: 6,797
|
Of course there are many ways to keep the line intact...
Code:
IFS='
'
for line in $(cat file); do
echo $line
done
|
|
|
07-25-2005, 12:49 PM
|
#10
|
Member
Registered: Aug 2003
Posts: 39
Original Poster
Rep:
|
Quote:
Originally posted by keefaz
Of course there are many ways to keep the line intact...
Code:
IFS='
'
for line in $(cat file); do
echo $line
done
|
=========================================================
hi keefaz,
I can't get this to work. The "echo $line" statement prints each item in a row from left to right instead of the entire row.
I don't understand what the " IFS=' " is for. Maybe that's my problem.
Please suggest another of the "many ways" to do this.
thanks
|
|
|
07-25-2005, 08:41 PM
|
#11
|
LQ Guru
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,430
|
As eddiebaby1023 implied, this is the sort of thing awk is designed for....
|
|
|
07-26-2005, 04:52 AM
|
#12
|
LQ Guru
Registered: Mar 2004
Distribution: Slackware
Posts: 6,797
|
km4hr, look closely...
Also could you post some lines of your data file ?
Last edited by keefaz; 07-26-2005 at 04:57 AM.
|
|
|
07-26-2005, 09:33 AM
|
#13
|
Member
Registered: Aug 2003
Posts: 39
Original Poster
Rep:
|
Quote:
Originally posted by keefaz
km4hr, look closely...
Also could you post some lines of your data file ?
|
====================================================================
Yes! That works. That's strange stuff. What does the tick on the line by itself do? My script works with or without it. I thought it was some artifact put there by mistake or something. My script doesn't complain about it being there. But it also works without it.
BTW, what's the deal with IFS. I noticed that "echo $IFS" doesn't work.
Example:
$ IFS=hello
$ echo $IFS
$
However:
$ echo "$IFS"
hello
$
Why?
Also, why do you have to set IFS inside the script. I tried setting it in the environment but the script doesn't see it. (Ex: At the command line I type " IFS=' " , " export IFS", then execute the script) How come?
|
|
|
07-26-2005, 11:20 AM
|
#14
|
LQ Guru
Registered: Mar 2004
Distribution: Slackware
Posts: 6,797
|
IFS: Internal Field Separator
(default value : <space><tab><newline>)
Try man bash and search for IFS and Word Splitting
|
|
|
07-26-2005, 12:34 PM
|
#15
|
LQ Guru
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326
|
this might already be mentioned but what if you cut-awk the first column, the middle, and the last column on separate lines (man cut and awk; they can work with last feild in a line):
tag1
this is tag1
good
tag2
this is tag2
bad
then hard-code your script accordingly (you'll know that 'tag1' is on every third line but will be transparent to the user). might be more work but it could be more fun.
sorry i'm at work so i have no tested code. i'll catch up with y'all when i get home.
thanks,
schneidz
|
|
|
All times are GMT -5. The time now is 10:28 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|