//View Tip #864
Similar Tips
» Generate a random password
» Create a Terminal Calculator
» .. revisited
» List non-system users
» another solution to #67

 

Latest tips by RSS
Click here to subscribe
Follow Shell-Fu on Twitter
Click here to follow
Follow Shell-Fu on identi.ca
Click here to follow
This short script reads a file line-by-line ( whith whitespace characters too ) and outputs to STDOUT.

#!/bin/bash
FILE='/path/to/filename'
for linecount in `seq $(cat $FILE | wc -l)`; do
line=`head -n$linecount $FILE | tail -1`
echo $line
done


View Comments »




Comments 

Add your comment

Comments are currently disabled
does not need $(cat $FILE | wc -l). It equal to $(wc -l $FILE).
Posted 2009-08-04 09:22:44
Useless use of cat.

Why not just use "read" with an empty IFS?
Posted 2009-08-04 09:49:05
Rob
How is the output of this script different to plain old "cat $FILE"?
Posted 2009-08-04 09:55:07
The UnDisbeliever
> How is the output of this script different to plain old "cat $FILE"?

This is something _useful_ that you can put in a shell script. For example, if you replace the

 echo $line

with a different command, you can get your script to execute the same command for each line in the file. I know it is horribly hacked together, but it works.


A better way to do this is by using the read command.

 while read line;
   # replace with command
   do echo ">" $line;
 done < l
Posted 2009-08-04 10:45:14
The UnDisbeliever
opps, I forgot to check my post before posting. The correct way of doing this should be;

while read line; do
  # replace with command
  echo ">" $line;
done < FILE_NAME
Posted 2009-08-04 10:48:11
Can Bican
You're kidding, right? I mean, reading a file over and over at each turn?

#!/bin/bash
FILE='/path/to/filename'
OIFS=$IFS
IFS='
'
for line in `cat $FILE`
do
 echo $line
done
IFS=$OIFS

or

'while read line' instead of the line with the 'for'. Just beware of IFS.
Posted 2009-08-04 10:50:11
The difference is fundamental... if you prefer this version:

#!/bin/bash

FILE=${1:-"/your/defaul/file"}


function handle_line( ) {

 echo ${1}
}


for lc in $(seq $(cat ${FILE} | wc -l)); do

 line=$(head -n$lc ${FILE} | tail -1)

 # This is the 'key'
 handle_line ${line}
done
Posted 2009-08-04 10:58:06
NSFW
Indeed the difference is fundamental. The complexity of line-by-line reading using head -$N is O(n²) instead of O(n). Try it on big files, you'll see the difference.

(nota : for the 1st line, you read 1 line. For the 2nd line, you read two, and so on. In the end, you'll have read 1+2+...+N lines instead of N, which is (N*(N+1))/2, hence O(n²).)

The for line in `cat $FILE` is fast, but such a memory bloat for big files.

Just use while read var; do ... done < $FILE, it's its very purpose.
Posted 2009-08-04 13:07:59
Mike
And another (one-liner)...


c=1; while [ ${c} -lt `wc -l ${FILE} | awk '{print $1;}'` ] ; do sed -n "${c},${c}p;${c}q" ${FILE}; c=$((${c}+1)); done
Posted 2009-08-04 14:57:33
OldUnix
The fundamental lesson here for everyone to learn is that *nix is flexible. For most common tasks, there are tens, of not hundreds of ways one can chose, and that's the beauty of *nix. Accomplish your goal whatever way you like, but the job gets done; unlike with the dictates and edicts of, for example Billware, where it's Bills way or, well, you know.
Posted 2009-08-04 14:57:43
Mike
Gah, change the '-lt' to '-le' in that one-liner...
Posted 2009-08-04 14:59:45
... WTF? That must be a joke.
Posted 2009-08-04 19:43:54
jackd
@OldLinux: What does this have to do with Microsoft? If anything, the lesson here is that you can write really bad code in any environment.

This script is really, really, really, really inefficient. And very convoluted for such a basic task.

A couple of previous some sensible implementations.
Posted 2009-08-05 04:05:05
lukas
while read
do
  echo "$REPLY"
done < file


BTW: examples with "read line" sometimes does not work.
Posted 2009-08-06 20:37:09
Chris Johnson
Not one of the solutions proposed so far will consistently read a full line into a variable. The closest will strip leading and trailing spaces and either drop backslashes or convert them into escape
sequences.

This script stores each full line in the variable $line:

while IFS= read -r line
do
 : do whatever with "$line"
done < "$file"
Posted 2009-08-28 23:49:18
Please stop shell scripting.
Posted 2009-08-30 10:57:22
To be more clear:

I didn't only mean the original poster. I mean min. 80% of the commenters, too.
Posted 2009-08-30 11:01:39
WTF
Got to love that thing in comment #9, it's so much more kewl than '' sed '$d' <"$file" ''.
Posted 2009-08-30 15:06:48

Home Latest Browse Top 25 Random Hall Of Fame Contact Submit