//View Tip #864
» Random line
» Diff Two Directories
» List non-system users
» Bash function to decompress archives
khsing
Similar Tips
» Stream shell commands to Twitter» Random line
» Diff Two Directories
» List non-system users
» Bash function to decompress archives
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
Comments
Add your comment
Comments are currently disabled
#1
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?
Why not just use "read" with an empty IFS?
Posted 2009-08-04 09:49:05
> 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
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
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
while read line; do
# replace with command
echo ">" $line;
done < FILE_NAME
Posted 2009-08-04 10:48:11
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.
#!/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
#!/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
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.
(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
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
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
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
@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.
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
while read
do
echo "$REPLY"
done < file
BTW: examples with "read line" sometimes does not work.
do
echo "$REPLY"
done < file
BTW: examples with "read line" sometimes does not work.
Posted 2009-08-06 20:37:09
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"
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
To be more clear:
I didn't only mean the original poster. I mean min. 80% of the commenters, too.
I didn't only mean the original poster. I mean min. 80% of the commenters, too.
Posted 2009-08-30 11:01:39

