Ksh Read a File Line By Line ( UNIX Scripting )

by on November 20, 2009 · 10 comments· last updated at December 5, 2009

How do I read a file line by line using KSH shell scripting under UNIX like operating systems?

You can use the while loop and read command to read a text file line by line under KSH.

KSH read while loop syntax

#!/bin/ksh
file="/path/to/file.txt"
# while loop
while read line
do
        # display line or do somthing on $line
	echo "$line"
done <"$file"

In this example, you are reading file separated by | fields. Sample domains.txt:

cyberciti.biz|74.86.48.99
nixcraft.com|75.126.168.152
theos.in|75.126.168.153
cricketnow.in|75.126.168.154
vivekgite.com|75.126.168.155
#!/bin/ksh
# set the Internal Field Separator to a pipe symbol
IFS='|'
 
# file name
file=/tmp/domains.txt
 
# use while loop to read domain and ip 
while read domain ip
do
	print "$domain has address $ip"
done <"$file"

However, following is recommend syntax to set the Internal field separator (see discussion below):

#!/bin/ksh
# file name
file=/tmp/domains.txt
 
# use while loop to read domain and ip 
# set the Internal Field Separator to a pipe symbol
while IFS=\| read domain ip
do
	print "$domain has address $ip"
done <"$file"

Suggested readings:

  • ksh man page

Updated for accuracy!



You should follow me on twitter here or grab rss feed to keep track of new changes.

Featured Articles:

{ 10 comments… read them below or add one }

1 Daniel J. Doughty November 20, 2009 at 5:00 pm

Thanks, I usually don’t like doing my heavy lifting with shell scripting. Still, this is useful information because sometimes the shell is all you have in the environment you’re working in.

Dan
It’s Unix Not Eunuchs

Reply

2 Joel November 20, 2009 at 10:15 pm

Thanks for the scripting tips, they really are the key to effective system administration tasks. The differences between the shells is new to me, I usually just use bash since it’s the default on the systems I use. I looked up the Korn shell on Wikipedia and it reports that it has backwards compatibility to the Bourne shell (which is Bash’s predecessor). On my system I did an experiment to see if the scripts would work with Bash and changed the #!/bin/ksh to #!/bin/sh. The first one works find, the second doesn’t – looks like it doesn’t support the “IFS” environment label. Interesting.

Now, if someone can explain the different between this alphabet soup and sym links that would be helpful (Ubuntu 8.04.1). Never heard of ‘dash’!

-rwxr-xr-x 1 root root 702160 May 12 2008 /bin/bash
-rwxr-xr-x 1 root root 79988 Mar 12 2008 /bin/dash
lrwxrwxrwx 1 root root 21 Nov 20 14:05 /bin/ksh -> /etc/alternatives/ksh
lrwxrwxrwx 1 root root 4 Apr 24 2008 /bin/sh -> dash

Reply

3 Shantanu Oak November 21, 2009 at 5:37 am

When there are a few lines to be read, I do always use the following method.

#!/bin/ksh
while read line
do
echo “$line”
done << iplist
cyberciti.biz|74.86.48.99
nixcraft.com|75.126.168.152
iplist

Reply

4 Vivek Gite November 21, 2009 at 9:44 am

@Joel,

The original sh is not available under Linux. dash is the standard command interpreter for the system. The current version of dash is in the process of being changed to conform with the POSIX 1003.2 and 1003.2a specifications for the shell. This version has many features which make it appear similar in some respects to the Korn shell, but it is not a Korn shell clone.

/etc/alternatives/ksh should point to to ksh93. Run the following

ls -l /etc/alternatives/ksh

sym links allows to use different version of ksh without breaking anything. update-alternatives command maintain symbolic links determining default commands for various system commands, and java. See man page

man ksh
man dash
man update-alternatives

Reply

5 Philippe Petrinko November 21, 2009 at 12:33 pm

dash is standard shell under UBUNTU,
(and should have been under Debian Lenny)
http://en.wikipedia.org/wiki/Debian_Almquist_shell

Reply

6 Brock Noland November 24, 2009 at 10:27 pm

Thanks for making people aware of native shell string splitting, but I would reset IFS.

Reply

7 Chris F.A. Johnson November 30, 2009 at 2:41 pm

The safe way to change IFS in a ‘while read’ loop is:

while IFS=\| read a b c
do
: whatever
done

Then it doesn’t affect anything but the read command.

Reply

8 Philippe Petrinko November 30, 2009 at 5:19 pm

To Chris : short and simple – How nice!
Should have think of this good old shell syntax
Good example of KISS principle … (ask Wikipedia)

Reply

9 ishan February 24, 2012 at 6:49 am

while reading line by line like this if you want to take user desire input
eg :-
cat use |while read mo
do
read -r o
if [[ $o = 'y' ]]
then
print “$mo”
else
print “kill me”
fi
done

In this case o/p will be always kill me …….user input wouldn’t be there so …..how to take user input in that

Reply

10 Philippe Petrinko February 24, 2012 at 11:35 am

@ishan

Solution is to separate user input from data input.
Use Vivek’s tutorial:
http://bash.cyberciti.biz/guide/Main_Page

A solution may be:

#!/bin/bash
# File descriptor #0 is stdin
# File descriptor #1 is stdout
# File descriptor #2 is stderr
# Let us assign extra file descriptor to file for input
# open for input file named "data" with fd #3
exec 3< data
# loop on fd #3
while read <&3
do
	# ask user input, by default on stdin
	read -p "Print next line of data ? (y/n):" answer
	# to debug, uncomment the following line
	# echo "Answer:${answer}:"
	# branch on answer, casted to lowercase
	if [[ "${answer,,}" = 'y' ]]
	then
		# user wants to see data
		# which is by default read in builtin REPLY variable
		echo $REPLY
	else
		# user wants to quit
		# let us terminate while loop
		break
	fi
done
# Close fd #3
exec 3<&-

HTH, Try it and let us know your solution.

– Philippe

Reply

Leave a Comment

You can use these HTML tags and attributes for your code and commands: <strong> <em> <ol> <li> <u> <ul> <kbd> <blockquote> <pre> <a href="" title="">

Tagged as: , , , , , , , , , , , , , ,

Previous Faq:

Next Faq: