How to Read the Last Line of a Text File into a Variable Using Bash

How to read the last line of a text file into a variable using Bash?

tag=$( tail -n 1 history.txt )

How to only read the last line from a text file

Use tail ;)

line=$(tail -n 1 input_file)
echo $line

Last line of a file is not reading in shell script

This is due to missing line break in the last line of your input file.

You can use this loop to read everything:

while IFS= read -r line || [ -n "$line" ]; do
echo "$line"
done < "$file"

For the last line without line break, read doesn't return a success hence [ -n "$line" ] check is done to make sure to print it when $line is not empty.

PS: If you don't mind changing your input file then use printf to append a newline using:

printf '\n' >> "$file"

And then read normally:

while IFS= read -r line; do
echo "$line"
done < "$file"

Bash get last line from a variable

Using bash string manipulations:

$> str="This is a
multiple line
variable test"

$> echo "${str##*$'\n'}"
variable test

${str##*$'\n'} will remove the longest match till \n from start of the string thus leaving only the last line in input.

Print last line of text file

awk to the rescue!

$ awk 'NF{a=b;b=$0} END{print "a="a;print "b="b}' file
a=1.2.4.t
b=complete

Or, if you want to the real variable assignment

$ awk 'NF{a=b;b=$0} END{print a, b}' file 
| read a b; echo "a="$a; echo "b="$b

a=1.2.4.t
b=complete

you may need -r option for read if you have backslashes in the values.

Read a file line by line assigning the value to a variable

The following reads a file passed as an argument line by line:

while IFS= read -r line; do
echo "Text read from file: $line"
done < my_filename.txt

This is the standard form for reading lines from a file in a loop. Explanation:

  • IFS= (or IFS='') prevents leading/trailing whitespace from being trimmed.
  • -r prevents backslash escapes from being interpreted.

Or you can put it in a bash file helper script, example contents:

#!/bin/bash
while IFS= read -r line; do
echo "Text read from file: $line"
done < "$1"

If the above is saved to a script with filename readfile, it can be run as follows:

chmod +x readfile
./readfile filename.txt

If the file isn’t a standard POSIX text file (= not terminated by a newline character), the loop can be modified to handle trailing partial lines:

while IFS= read -r line || [[ -n "$line" ]]; do
echo "Text read from file: $line"
done < "$1"

Here, || [[ -n $line ]] prevents the last line from being ignored if it doesn't end with a \n (since read returns a non-zero exit code when it encounters EOF).

If the commands inside the loop also read from standard input, the file descriptor used by read can be chanced to something else (avoid the standard file descriptors), e.g.:

while IFS= read -r -u3 line; do
echo "Text read from file: $line"
done 3< "$1"

(Non-Bash shells might not know read -u3; use read <&3 instead.)

Read last line of file in bash script when reading file line by line

It sounds like your input file is missing the newline character after its last line. When read encounters this, it sets the variable ($line in this case) to the last line, but then returns an end-of-file error so the loop doesn't execute for that last line. To work around this, you can make the loop execute if read succeeds or it read anything into $line:

...
while read line || [[ -n "$line" ]]; do
...

EDIT: the || in the while condition is what's known as a short-circuit boolean -- it tries the first command (read line), and if that succeeds it skips the second ([[ -n "$line" ]]) and goes through the loop (basically, as long as the read succeeds, it runs just like your original script). If the read fails, it checks the second command ([[ -n "$line" ]]) -- if read read anything into $line before hitting the end of file (i.e. if there was an unterminated last line in the file), this'll succeed, so the while condition as a whole is considered to have succeeded, and the loop runs one more time.

After that last unterminated line is processed, it'll run the test again. This time, the read will fail (it's still at the end of file), and since read didn't read anything into $line this time the [[ -n "$line" ]] test will also fail, so the while condition as a whole fails and the loop terminates.

EDIT2: The [[ ]] is a bash conditional expression -- it's not a regular command, but it can be used in place of one. Its primary purpose is to succeed or fail, based on the condition inside it. In this case, the -n test means succeed if the operand ("$line") is NONempty. There's a list of other test conditions here, as well as in the man page for the test command.

Note that a conditional expression in [[ ... ]] is subtly different from a test command [ ... ] -- see BashFAQ #031 for differences and a list of available tests. And they're both different from an arithmetic expression with (( ... )), and completely different from a subshell with( ... )...

Reading everything but first and last line into a string in bash

sed would be ideal for this job.

To strip off the first and final lines, use

sed '1d;$d' server.csr

Or if you'd like to be more precise, try

sed '/-----\(BEGIN\|END\) CERTIFICATE REQUEST-----/d'  server.csr

To read the result into a variable, use the shell $() syntax:

csrfile=$(sed '/-----\(BEGIN\|END\) CERTIFICATE REQUEST-----/d'  server.csr)


Related Topics



Leave a reply



Submit