1

i want to read a file and print it on the screen by shell scripting , so i have find a simple code to do this :

#! /bin/bash 

FILENAME=$1
Lines=$(wc -l < $FILENAME)

count=0

while [ $count -lt $Lines ]
do
    let count++
    LINE= `head -n $count $FILENAME | tail -1 `
    echo "$count $LINE"
done
echo -e "\nTotal $count lines read"

, but i'm didn't understand the following line :

LINE= `head -n $count $FILENAME | tail -1 `

any help ??

4 Answers 4

1

This will first run head on the file, taking the first $count lines of the file. It is then piped (|) into tail, which (due to the -1) will return only the last line of the output of head (i.e. the countth line).

This will then get assigned to the LINE variable for processing

It's worth noting that this approach will work, but it is very inefficient.

Sign up to request clarification or add additional context in comments.

4 Comments

okay , that's good , but for -n , is it have an espicial meaning ?
by default head will return the first 10 lines of input. -n X tells head to return the first X lines instead. the -1 parsed to the tail call is actually a short-hand for -n 1
and another question , why this approach is inefficent ?
the inefficiency is because you are reading the file repeatedly rather than just once (look up the while read construct)
1

The line

LINE= `head -n $count $FILENAME | tail -1 `

doesn't do what you think it should. It tries to execute the command produced by the output of

head -n $count $FILENAME | tail -1

with a variable LINE (without a value) passed to it.

Instead say:

LINE=$(head -n $count $FILENAME | tail -1)

which would essentially give the line number count in the file.


As an alternate, you could say:

LINE=$(sed -n ${count}'p' $FILENAME) 

to get the line.


Your script seems to be emulating

cat -n filename

Comments

1

Very inefficient as others have pointed out. @devnull's observation cat -n file is spot on.

To emulate that in bash, I'd write:

declare -i linenum=0
while IFS= read -r line; do
    printf "%8d  %s\n" $((linenum++)) "$line"
done < file

3 Comments

i have seen a lot about environment variable IFS , could you tell me what is it ?
The bash manual defines IFS as "A list of characters that separate fields; used when the shell splits words as part of expansion." Details at gnu.org/software/bash/manual/bashref.html#Word-Splitting
Example: line="1:2:3"; IFS=: read a b c <<< "$line"; echo $a; echo $b; echo $c
0

the following simple script will help

readfile.sh

file=$1

cat $file | while read line
do
    echo $line
done

Reading file into an array,

readfileAsArray.sh

file=$1

let index=1

while IFS=$'\n' read -r -a myArray
do
    file_content_array[$index]="${myArray[0]}"
    echo ${file_content_array[$index]}
    let index=$index+1
done < $file

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.