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.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
07-19-2009, 05:56 AM
|
#1
|
|
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:
|
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 06:16 AM.
|
|
|
|
07-19-2009, 07:00 AM
|
#2
|
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,577
|
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 07:04 AM.
|
|
|
|
07-19-2009, 07:04 AM
|
#3
|
|
Senior Member
Registered: Aug 2006
Posts: 2,695
|
Code:
awk '{t+=length}END{print t}' file
|
|
|
|
07-19-2009, 07:06 AM
|
#4
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,357
|
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 07:10 AM.
Reason: See comment in post
|
|
|
|
07-19-2009, 07:18 AM
|
#5
|
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,577
|
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.
|
|
|
|
07-19-2009, 08:24 AM
|
#6
|
|
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:
|
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 08:25 AM.
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 05:24 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
|
|