LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
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 01-06-2013, 11:08 PM   #1
Zixy
LQ Newbie
 
Registered: Jan 2013
Posts: 6

Rep: Reputation: Disabled
[Bash] Process lines from file one at a time.


Currently, I have code which reads from a file. That bit works. I'd like to process each line on the file one at a time.

Currently my code (edited for secuirty) is

Code:
while read LINE 
 do
    if [ my file exists ] 
       then
		echo "Do action A or B"
		read ANSWER
		if [ $ANSWER = "A" ] 
       then
			do whatever
		elif [ $ANSWER = "B" ]; then
			do something else
		fi
	fi
done < "$FILENAME"
However, it checks all lines at once.

So I can't do A or B to the lines that need different options.

I need one line to be processed at a time.


Sorry if I am unclear! If you have any questions, I will try my best to answer them!
 
Old 01-07-2013, 12:56 AM   #2
Stéphane Ascoët
Member
 
Registered: Feb 2004
Location: Fleury-les-Aubrais, 120 km south of Paris
Distribution: Devuan, Debian, Mandrake, Freeduc (the one I used to work on), Slackware, MacOS X
Posts: 251

Rep: Reputation: 49
Post

Test the existence of the file first, and then, use "for l in file" instead of "while read line"
 
1 members found this post helpful.
Old 01-07-2013, 01:59 AM   #3
Zixy
LQ Newbie
 
Registered: Jan 2013
Posts: 6

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Stéphane Ascoët View Post
Test the existence of the file first, and then, use "for l in file" instead of "while read line"
Could you show me that with my code please, I am a bit confused to what you are saying.
 
Old 01-07-2013, 02:12 AM   #4
Stéphane Ascoët
Member
 
Registered: Feb 2004
Location: Fleury-les-Aubrais, 120 km south of Paris
Distribution: Devuan, Debian, Mandrake, Freeduc (the one I used to work on), Slackware, MacOS X
Posts: 251

Rep: Reputation: 49
Post

if [ my file exists ]
then
for l in `cat file`
echo "Do action A or B"
read ANSWER
if [ $ANSWER = "A" ]
then
do whatever
elif [ $ANSWER = "B" ]; then
do something else
fi
 
1 members found this post helpful.
Old 01-07-2013, 03:07 AM   #5
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
If you process $LINE won't that be one line at a time?
 
1 members found this post helpful.
Old 01-07-2013, 08:32 AM   #6
Zixy
LQ Newbie
 
Registered: Jan 2013
Posts: 6

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Stéphane Ascoët View Post
if [ my file exists ]
then
for l in `cat file`
echo "Do action A or B"
read ANSWER
if [ $ANSWER = "A" ]
then
do whatever
elif [ $ANSWER = "B" ]; then
do something else
fi
I have to check if the file exists using the line from the file. (It's a list of possible directory names.)
 
Old 01-07-2013, 08:33 AM   #7
Zixy
LQ Newbie
 
Registered: Jan 2013
Posts: 6

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by konsolebox View Post
If you process $LINE won't that be one line at a time?
I was originally, but the guy above said that doesn't work :P
 
Old 01-07-2013, 08:58 AM   #8
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by Stéphane Ascoët View Post
Test the existence of the file first, and then, use "for l in file" instead of "while read line"
This is not advisable: if a line contains spaces it will be split in fields and the loop will make an iteration over each field.
 
1 members found this post helpful.
Old 01-07-2013, 09:03 AM   #9
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by Zixy View Post
I was originally, but the guy above said that doesn't work :P
Who said that? Actually your script should work. You can easily test it by adding a counter, as in:
Code:
while read line
do
  echo $((++c)): "$line"
done < "$FILENAME"
or put
Code:
#!/bin/bash -x
at the beginning of your script to see the execution flow. Useful for debugging in general.

Last edited by colucix; 01-07-2013 at 09:04 AM.
 
1 members found this post helpful.
Old 01-07-2013, 09:09 AM   #10
Zixy
LQ Newbie
 
Registered: Jan 2013
Posts: 6

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by colucix View Post
Who said that? Actually your script should work. You can easily test it by adding a counter, as in:
Code:
while read line
do
  echo $((++c)): "$line"
done < "$FILENAME"
or put
Code:
#!/bin/bash -x
at the beginning of your script to see the execution flow. Useful for debugging in general.
I thought I had read it. It turns out that I was that guy above!

I'm going to go work on it some more and I will get back to you with results. All help is appreciated.
 
Old 01-07-2013, 10:53 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
I would point out that a little gotcha is in your original code, which is that if you call read on stdin (look inside your "if") then it will draw the answer from the
open file descriptor which is already being read from, ie $FILENAME
 
2 members found this post helpful.
Old 01-07-2013, 11:11 AM   #12
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by grail View Post
I would point out that a little gotcha is in your original code, which is that if you call read on stdin (look inside your "if") then it will draw the answer from the
open file descriptor which is already being read from, ie $FILENAME
Good catch, grail!

In this case, what do you think about redirecting the input from the file using an unused file descriptor and feed the while read loop from there? Example:
Code:
exec 3< $FILENAME
while read line <&3
do
  read answer
  echo $((++c)): $line $answer
done
exec 3>&-
 
1 members found this post helpful.
Old 01-07-2013, 12:11 PM   #13
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Yeah that would work, although I do quite like -u option for read to make it a little easier to follow:
Code:
exec 3< $FILENAME

while read -u3 line
do
...
 
2 members found this post helpful.
Old 01-07-2013, 02:27 PM   #14
Zixy
LQ Newbie
 
Registered: Jan 2013
Posts: 6

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by grail View Post
Yeah that would work, although I do quite like -u option for read to make it a little easier to follow:
Code:
exec 3< $FILENAME

while read -u3 line
do
...
This did it!

Thank you for everyone's help. I really do appreciate it.
 
Old 01-07-2013, 08:48 PM   #15
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Quote:
Originally Posted by colucix View Post
Code:
exec 3>&-
That should be:
Code:
exec 3<&-
And this should be similar:
Code:
{
    ... do other things

    while read -u 3 LINE; do
        echo "$LINE"
    done

    ... do other things
} 3< "$FILENAME"
Or just:
Code:
while read -u 3 LINE; do
    echo "$LINE"
done 3< "$FILENAME"
With that we no longer have to close file descriptors with exec N<&-.
 
  


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
Getting Same Lines from File(BASH) eawedat Programming 23 09-13-2012 12:55 PM
Basic bash script question re: file size or # of lines in a file the_fornicator Programming 6 09-03-2009 09:41 AM
bash - how to terminate a process after certain time alan43 Linux - Newbie 1 03-12-2009 02:35 PM
time a process within bash script aubrey-calm2 Linux - General 2 06-15-2007 01:39 PM
[bash] remove lines from a file Drimo Programming 3 03-20-2004 11:16 AM

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

All times are GMT -5. The time now is 07:59 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