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. |
|
 |
08-11-2009, 08:41 AM
|
#1
|
|
Member
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 725
Rep:
|
Bash scripting: parsing a text file character-by-character
Hi all,
Is there a way to process individual characters one-by-one from a text file in Bash, or is that hoping for a little too much from this lovable old clunker?
Thanks,
cc
|
|
|
|
08-11-2009, 09:16 AM
|
#2
|
|
Member
Registered: Apr 2009
Location: ~
Distribution: RHEL, Fedora
Posts: 381
Rep:
|
Not the exact solution of your problem but might take you to the right path
Code:
sed 's/\(.\)/\1\n/g' <file>
|
|
|
|
08-11-2009, 09:30 AM
|
#3
|
|
Senior Member
Registered: Nov 2005
Distribution: Debian
Posts: 2,022
|
Code:
~$ help read
read: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
...
If -n is supplied with a non-zero NCHARS argument, read returns after NCHARS
characters have been read.
|
|
|
|
08-11-2009, 10:10 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,358
|
Quote:
Originally Posted by Completely Clueless
lovable old clunker
|
So ya seein' the light, huh?  Praise be and pass the pipe!
|
|
|
|
08-11-2009, 10:25 AM
|
#5
|
|
Member
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 725
Original Poster
Rep:
|
Quote:
Originally Posted by catkin
So ya seein' the light, huh?  Praise be and pass the pipe!
|
Hello Charles,
Well I'm simply more realistic about Bash's capabilities now I know how it arose and what for.
This task is something I could jot down on the back of a fag packet in C, but that was very many years ago and I can't recall the relevant functions. ISTR C has a getchar() function which does this. I need a Bash equivalent that I can run in an 'until' loop until the next character read from the file is EOF.
It's annoying that so much I want to do in Linux is usually something I've yet to learn!
|
|
|
|
08-11-2009, 11:01 AM
|
#6
|
|
Amigo developer
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,592
|
Code:
while read -n 1 ; do
# do something
done < file
|
|
|
|
08-11-2009, 12:01 PM
|
#7
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,358
|
Quote:
Originally Posted by Completely Clueless
This task is something I could jot down on the back of a fag packet in C, but that was very many years ago and I can't recall the relevant functions. ISTR C has a getchar() function which does this. I need a Bash equivalent that I can run in an 'until' loop until the next character read from the file is EOF.
It's annoying that so much I want to do in Linux is usually something I've yet to learn!
|
Ah, the delights of steep learning curves!
Solutions already posted show how to do what you want in bash; if you want to do a non-blocking read -- simple in C -- then things get a little more "interesting"
ISTR that getchar() and putchar() are actually C #define macros that hide an underlying buffer for convenience and performance but that also comes from "very many years ago" so take it with a pinch of salt.
|
|
|
|
08-11-2009, 12:02 PM
|
#8
|
|
Member
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 725
Original Poster
Rep:
|
Quote:
Originally Posted by gnashley
Code:
while read -n 1 ; do
# do something
done < file
|
That looks promising. I'll give it a try and report back later. Thanks.
|
|
|
|
08-11-2009, 06:03 PM
|
#9
|
|
Member
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 725
Original Poster
Rep:
|
Okay, well we're off and running, but a few teething problems. This is the relevant code fragment as it stands after some tinkering:
Code:
#!/bin/bash
#process a text file character-by-character
# the variable '$char' is the individual file character under test
x=1
while read -n$x char
do
echo -n "iteration number $x:"
echo " $char"
x=$[ $x + 1 ]
done < textfile.txt
The problem is that I'm incrementing the -n of 'read' using the variable $x each time the loop iterates, but each time read functions, it's reading longer and longer strings from the file each time around. I only want it to fetch *one* character at a time to test on; kind of like a pointer moving up an array one element at a time.
How do I tell 'read' to just fetch one character each time, but every iteration make it take the *next* character and so on in sequence until the end of the file is reached?
Thanks, guys.
cc
|
|
|
|
08-11-2009, 07:49 PM
|
#10
|
|
Senior Member
Registered: Aug 2006
Posts: 2,695
|
Quote:
Originally Posted by Completely Clueless
Hi all,
Is there a way to process individual characters one-by-one from a text file in Bash, or is that hoping for a little too much from this lovable old clunker?
Thanks,
cc
|
use awk
Code:
awk 'BEGIN{FS=""}{
for(i=1;i<=NF;i++){ print "do something with "$i }
}' file
|
|
|
|
08-11-2009, 08:15 PM
|
#11
|
|
Senior Member
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 2,967
Rep: 
|
Quote:
Originally Posted by catkin
ISTR that getchar() and putchar() are actually C #define macros that hide an underlying buffer for convenience and performance but that also comes from "very many years ago" so take it with a pinch of salt.
|
(taking the tangent...) It doesn't make a lot of sense to use an input buffer in that manner, anyway. In C you could read in a line of text, then process it a character at a time from an array. If the objective was to react to keyboard input immediately, the read system call would be more appropriate (after changing the terminal settings) with a requested size of 1. I think the objective of getchar is to avoid incrementing the buffer by an entire line, or to simulate read when one is predominantly using text input.
Kevin Barry
|
|
|
|
08-12-2009, 01:57 AM
|
#12
|
|
Amigo developer
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,592
|
Code:
#!/bin/bash
#process a text file character-by-character
# the variable '$char' is the individual file character under test
count=1
while read -n1 char
do
echo -n "iteration number $count:"
echo " $char"
(( count++ ))
done < textfile.txt
|
|
|
|
08-12-2009, 04:18 AM
|
#13
|
|
Member
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 725
Original Poster
Rep:
|
Excellent work, Gnashley! Works like a charm. 
|
|
|
|
08-12-2009, 09:07 AM
|
#14
|
|
LQ 5k Club
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian Squeeze (server), Slackware 13.37 (netbook), Slackware64 14.0 (desktop),
Posts: 8,358
|
In case you're interested in why Gnashley's solution works ...
textfile.txt is opened only once, by the indirection operator < on the while; do; <commands>; done compound command.
I guess you were thinking it was the read command that opened textfile.txt when you coded while read -n$x char
|
|
|
|
| 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:22 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
|
|