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=
(orIFS=''
) 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
How to Change Port Number for Jenkins Installation in Ubuntu 12.04
How to Gzip Standard in to a File and Also Print Standard in to Standard Out
How to Capture Network Frames in a Kernel Module
Rename Multiple Directories Matching Pattern
How to Implement a Practical Fiber Scheduler
Add Some Specific Time While Using the Linux Command "Date"
How to "Interconnect" Two Sockets in Linux
Fast Way to Find Difference Between Two Strings of Equal Length in Perl
How to Read the Second-To-Last Line in a File Using Bash
Using the Universal Chess Interface
Using Perf to Monitor Raw Event Counters
Arm Linux Atags VS Device Tree
How to Limit the Cache Used by Copying So There Is Still Memory Available for Other Caches
How to Check Whether the Processor Cache Has Been Flushed Recently
How to Check If Find Command Didn't Find Anything
What's the Difference B/W _Raw_Readl/_Raw_Writel and Readl/Writel in Linux Kernel