LinuxQuestions.org
Share your knowledge at the LQ Wiki.
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 07-19-2009, 06:56 AM   #1
J_Szucs
Senior Member
 
Registered: Nov 2001
Location: Budapest, Hungary
Distribution: SuSE 6.4-11.3, Dsl linux, FreeBSD 4.3-6.2, Mandrake 8.2, Redhat, UHU, Debian Etch
Posts: 1,126

Rep: Reputation: 58
bash: variables inside while loop


I am not quite unfamiliar with bash scripts, yet, I am faced with a rather lame problem.

I have a short bash script code that is something like this:

Code:
IFS="
"
cat $file | while read line; do
  len=${#line}
  let "total = $total + $len"
  echo "$total"
done
echo "$total"
My problem is that the value of variable "total" is always zero outside the loop. I.e. the final echo command always reports 0, whilst the echo command inside the while loop reports the correct total.

Are bash variables local to the while loop in this syntax? If yes, is there a workaround, to use their values outside the loop?

P.S.
The above code snippet is of course just a meaningless example to show the problem. The code would be part of a script that splits up a large text file into smaller chunks having a fixed maximum number of characters.
The "split" command has proven to be unsuitable for this purpose, as it happily breaks unicode characters in two.
Anyway, if there is an other code snipped for the purpose using bash/awk/sed, it would be welcome.

Last edited by J_Szucs; 07-19-2009 at 07:16 AM.
 
Old 07-19-2009, 08:00 AM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950
The external call works if you use redirection instead of a pipe. I'm not sure why though. It probably has something to do with the loop running in a subshell.

Code:
IFS="
"

while read line; do
  len=${#line}
    let "total = $total + $len"
    echo "$total"
done  <$file

echo "$total"
Besides, redirection is a bash built-in function, so it's more efficient than having to call the external cat command.

Edit: The ABSG has this to say:

Quote:
A pipe runs as a child process, and therefore cannot alter script variables.

Last edited by David the H.; 07-19-2009 at 08:04 AM.
 
Old 07-19-2009, 08:04 AM   #3
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 241Reputation: 241Reputation: 241
Code:
awk '{t+=length}END{print t}' file
 
Old 07-19-2009, 08:06 AM   #4
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,563
Blog Entries: 29

Rep: Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179
Hello J_Szucs

cat $file | while sets up a pipeline with the while running in a subshell. Variable settings made in the subshell are lost when the subshell exits.

Using input redirect avoids the problem
Code:
while IFS='
' read line
do
  len=${#line}
  let "total = $total + $len"
  echo "$total"
done < input
echo "Loop done, total: $total"
I just found out in another thread that the above idiom saves you having to reset IFS after the loop (but you may want its usual value in the loop, in which case it's no good o)).

Edit: David the H said it while I was typing

Best

Charles

Last edited by catkin; 07-19-2009 at 08:10 AM. Reason: See comment in post
 
Old 07-19-2009, 08:18 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950
PS: can you explain in more detail exactly what you're trying to accomplish in "splitting a large text file"? Please give us an example of the text you want to split, and the final form you want it to be in, so we can help you find the solution you need.
 
Old 07-19-2009, 09:24 AM   #6
J_Szucs
Senior Member
 
Registered: Nov 2001
Location: Budapest, Hungary
Distribution: SuSE 6.4-11.3, Dsl linux, FreeBSD 4.3-6.2, Mandrake 8.2, Redhat, UHU, Debian Etch
Posts: 1,126

Original Poster
Rep: Reputation: 58
Thanks for your help, redirection works like a charm!

P.S.
The code is part of a larger converter script that makes e-books (in the most common document formats, except lit) readable by iPod (in iPod Note format).
The e-book is first converted to an UTF8 text file, then split up to max. 4012-characters-long chunks (iPod Note), each having a html-like link at the end to the next chunk.

Last edited by J_Szucs; 07-19-2009 at 09:25 AM.
 
  


Reply


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
Assigning variables in a bash for loop JDska55 Linux - Newbie 6 06-18-2009 04:37 PM
how to stop parsing shell variables in bash script inside cat area? jackandking Linux - Newbie 2 03-10-2009 07:44 AM
Bash: command works but not inside of for loop. RijilV Programming 3 05-21-2006 09:29 PM
Bash - Getting a for loop to process variables with a space in them davee Linux - General 4 10-08-2005 12:21 PM
BASH variables getting unset outside of loop trevelluk Programming 2 03-25-2005 08:14 AM


All times are GMT -5. The time now is 07:40 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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration