LinuxQuestions.org
Visit Jeremy's Blog.
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-20-2004, 02:06 PM   #1
Darren[UoW]
LQ Newbie
 
Registered: Jan 2004
Posts: 1

Rep: Reputation: 0
bash shell script read file line by line.


I am using the following code to read line by line from a file, however my problem is that $value=0 at the end of the loop possibly because bash has created a subshell for the loop or something similar. How can I solve this.


value=0;

while read line
do
value=`expr $value + 1`;
echo $value;
done < "myfile"

echo $value;


Note: This example just counts the number of lines, I actually desire to do more complex processing than this though, so 'wc' is not an alternative, nor is perl im afraid.


Thanks Darren.
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 01-20-2004, 02:27 PM   #2
TheOther1
Member
 
Registered: Feb 2003
Location: Atlanta, GA
Distribution: RHAS 2.1, RHEL3, RHEL4, SLES 8.3, SLES 9, SLES9_64, SuSE 9.3 Pro, Ubuntu, Gentoo
Posts: 335

Rep: Reputation: 32
I think value may be a reserved word, maybe? I used a=$(($a+1)); instead of value=`expr $value + 1`; but it essentially the same. Replacing value with a seemed to work:
Code:
a=0
while read line
do a=$(($a+1));
echo $a;
done < "myfile"
echo "Final line count is: $a";
 
1 members found this post helpful.
Old 01-20-2004, 03:43 PM   #3
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Strange, I copied/pasted the first script (Darren's) into emacs. Put #!/bin/bash at the first line. chmod +x the script. And made a dummy "myfile" containing 23 lines of rubish.

And it worked!

(Debian testing/sarge w/ bash 2.05b.0(1) )
 
Old 01-21-2004, 01:42 AM   #4
Strike
Member
 
Registered: Jun 2001
Location: Houston, TX, USA
Distribution: Debian
Posts: 569

Rep: Reputation: 31
Actually, if awk is available, that would be better
 
1 members found this post helpful.
Old 01-21-2004, 08:06 AM   #5
TheOther1
Member
 
Registered: Feb 2003
Location: Atlanta, GA
Distribution: RHAS 2.1, RHEL3, RHEL4, SLES 8.3, SLES 9, SLES9_64, SuSE 9.3 Pro, Ubuntu, Gentoo
Posts: 335

Rep: Reputation: 32
Quote:
nor is perl im afraid.
Perl is actually excellent for text maniplulation and has sed, awk and many other native utilities capablilites built in. With modules from CPAN you do pretty close to anything with perl.
 
1 members found this post helpful.
Old 01-21-2004, 11:58 PM   #6
narendra_i
LQ Newbie
 
Registered: Sep 2003
Location: hyderabad
Posts: 12

Rep: Reputation: 1
#!bin/bash

while read line
do
echo $line
done
 
1 members found this post helpful.
Old 01-22-2004, 01:06 AM   #7
paonethestar
Member
 
Registered: Oct 2003
Posts: 47

Rep: Reputation: 16
Code:
 #!/bin/sh
  echo enter file name
  read fname
   
   exec<$fname
   value=0
   while read line
   do
            value=`expr $value + 1`;
            echo $value;
   done
   echo "****$value";
Above code worked fine in Redhat 9.0 . I don't know what is ur problem here ? If u have even some more doubts at this code , inform me. Bye.
 
1 members found this post helpful.
Old 03-21-2004, 11:53 PM   #8
ojeknyolot
LQ Newbie
 
Registered: Mar 2004
Posts: 1

Rep: Reputation: 3
Bash's sh emulation (that is if a script is called with /bin/sh instead of /bin/bash) does not spawn a subshell for that kind of while loop invloving IO redirection. Traditional sh as the one found in Solaris does.

A quick and dirty solution would be to save the result in a temporary file.

Code:
#!/bin/sh
TMPFILE="/tmp/test.$$.`whoami`"

n=0
while read curline; do
    n=`expr $n + 1`
    echo "$n" > $TMPFILE
done < "yourfile"
n=`cat $TMPFILE`
echo "Total: $n"
                                                                                                                             
rm -f $TMPFILE
Still I'd like to know if there are more elegant solutions.

Cheers,

Ronny
 
3 members found this post helpful.
Old 09-22-2005, 02:25 PM   #9
ldp
Member
 
Registered: Apr 2004
Location: Belgium Antwerpen
Distribution: slackware - knoppix
Posts: 141

Rep: Reputation: 18
Hi, I don't know if anyone still reads this but when I try to read a file line by line, I use something like "head -n $x filename | tail -n 1" where $x loops from 1 through the amount of lines in the file which can easily be found using "wc -l filename"
Does this make any sense or isn't it what you're looking for.
cheers!
 
Old 09-22-2005, 03:20 PM   #10
ldp
Member
 
Registered: Apr 2004
Location: Belgium Antwerpen
Distribution: slackware - knoppix
Posts: 141

Rep: Reputation: 18
In fact, what's bothering me is that wc doesn't just return the number of lines in the file but also the name of the file which made it unusable in a conditional statement... (damn you! damn you, wc!)
I had to trick it like this:

**********************************
#!/bin/bash
# read a file line by line

file=/mnt/hdb/backupscripts/backup.conf

x=0
lns=`wc -l $file`
y=`expr "$lns" : '\([0-9]*\)'`
while [ "$x" -lt "$y" ]
do
let x=x+1
head -n $x $file | tail -n 1
done

exit 0
***********************************

If you see a more elegant way, please let me know.

thanks.
 
2 members found this post helpful.
Old 09-22-2005, 03:46 PM   #11
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Quote:
In fact, what's bothering me is that wc doesn't just return the number of lines in the file but also the name of the file which made it unusable in a conditional statement... (damn you! damn you, wc!)
what about:
Code:
while [ $x -lt $(cat $file | wc -l) ]
do
   ...
?
 
2 members found this post helpful.
Old 09-25-2005, 10:32 AM   #12
eddiebaby1023
Member
 
Registered: May 2005
Posts: 378

Rep: Reputation: 33
Quote:
Originally posted by jlliagre
what about:
Code:
while [ $x -lt $(cat $file | wc -l) ]
do
   ...
?
The clever way to get rid of that pesky filename is not to give it!
Code:
while [ $x -lt $(wc -l <$file) ]
do
  ...
 
3 members found this post helpful.
Old 09-25-2005, 10:41 AM   #13
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Yep, that one is better !
 
0 members found this post helpful.
Old 06-14-2006, 04:08 PM   #14
jtmoon
LQ Newbie
 
Registered: Jun 2006
Location: WA, USA
Distribution: Fedora Core 10
Posts: 16

Rep: Reputation: 5
Unhappy while read line giving giving the directory listing instead of just the file!?

I am having a lot of trouble with this form of the read line script.

Code:
oneLineFile= 
for myFile in `dir`
do 
  while read myLine
  do
     oneLineFile="$oneLineFile$myLine"
  done < $myFile
  echo $oneLineFile
  echo ------------
done
For some reason while read myLine spits out the directory listing after it has read the entire file!

For example, a file with contents
Code:
hello 
from some  
file

in the directory with `dir` listing:
Code:
file1.txt
file2.txt 
...
file99.txt

yields output:
hello from some file file1.txt file2.txt ... file99.txt
------------



My guess is read myLine is not returning the correct value that would exit the while loop. And so it just keeps reading on up the stack where the `dir` output is stored.

I am using
GNU bash, version 3.1.17(6)-release (i686-pc-cygwin)

-J Tom Moon

Last edited by jtmoon; 06-14-2006 at 04:18 PM. Reason: add an example
 
1 members found this post helpful.
Old 06-14-2006, 04:38 PM   #15
jtmoon
LQ Newbie
 
Registered: Jun 2006
Location: WA, USA
Distribution: Fedora Core 10
Posts: 16

Rep: Reputation: 5
Thumbs down read line use `cat $file` instead of just $file

Nevermind!

After many stoooopid problems (too many to repeat) I finally went with this solution:

File rmLines.sh
Code:
for myFile in `dir` 
do 
  /helper.sh "$myFile"
done
File helper.sh
Code:
  echo 1 is $1
  cat $1 | while myLine=`line`
  do
     temp="$allFile"
     allFile="$temp $myLine" 
     echo "$allFile" > ../edit/$1
  done 
Perhaps this has something to do with CR/CL line endings in Windows text files?
Or just a problem with cygwin bash?

I would *swear* that my first attempt would have worked under bash on my Fedore Core machine.

-J_Tom_Moon_79

UPDATE 2009/4/22 :
See my last post in this thread for a better solution:
http://www.linuxquestions.org/questi...ml#post3517917

Last edited by jtmoon; 04-22-2009 at 10:32 PM. Reason: final result
 
2 members found this post helpful.
  


Reply

Tags
content, do, file, from, how, name, possibilities, read, script, write


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
BASH: read every line in the files and use the line as parameters as another program tam3c36 Programming 10 12-07-2010 01:42 PM
bash: read a line from file zokik Linux - General 6 12-10-2008 09:24 AM
shell script that read each line separatly xpucto Programming 6 09-20-2005 08:06 AM
Shell Script to read 500files from the command line saravanan1979 Programming 1 09-22-2004 09:44 AM
linux scripting help needed read from file line by line exc commands each line read atokad Programming 4 12-26-2003 10:24 PM

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

All times are GMT -5. The time now is 10:44 PM.

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