How to read the second-to-last line in a file using Bash?
Try this:
tail -2 yourfile | head -1
Print second last line from variable in bash
You almost done this task by yourself. Try
VAR="1\n2\n3"; printf -- "$VAR"|tail -2|head -1
How to insert a string into second to last line of a file
You can use sed
to insert a line before a specific line, given it's position :
sed '4i\My New Line\' my_file.txt
Will insert "My New Line" on the fourth line
You can use wc -l
to get the number of line in the file :
$ wc -l < my_file.txt
5
Complete example to directly answer your question :
$ cat my_file.txt
Hello
World
There is another line
$ sed -i "`wc -l < my_file.txt`i\\My New Line\\" my_file.txt
$ cat my_file.txt
Hello
World
My New Line
There is another line
- Adding
-i
so sed actually edit the file - Using double quotes, otherwise substitution and expansion is not performed within single quotes.
- Escaping
\
Replace the pattern on second-to-last line of a file
To change Sweet to Green on the second to last line but only if that line contains Sweet pepper
:
$ sed 'x; ${/Sweet pepper/s/Sweet/Green/;p;x}; 1d' file.txt
cabbage
spinach
collard greens
corn salad
Green pepper
kale
To replace the whole of the second to last line, regardless of what it contains, to carrots:
$ sed 'x; ${s/.*/carrots/;p;x}; 1d' file.txt
cabbage
spinach
collard greens
corn salad
carrots
kale
How it works
Let's take this command and examine it one step at a time:
sed 'x; ${s/.*/carrots/;p;x}; 1d'
x
This exchanges the pattern space (which holds the most recently read line) and the hold space.
When this is done, the hold space will contain the most recently read line and the pattern space will contain the previous line.
(The exception is when we have just read the first line. In that case, the hold space will have the first line and the pattern space will be empty.)${s/.*/carrots/;p;x}
When we are on the last line, indicated by the
$
, the pattern space holds the second to last line and we can perform whatever substitutions or other commands that we like. When we are done, we print the second to last line withp
. Lastly, we swap pattern and hold space again withx
so that the pattern space will again contain the last line.sed
will print this because, by default, at the end of the commands,sed
prints whatever is in the pattern space.1d
When we are on the first line, indicated by the
1
, the patten space is empty (because there was no previous line) and we delete it (d
).
A still simpler method
This method is easy to understand at the cost of slower execution speed:
$ tac file.txt | sed '2 {/Sweet pepper/s/Sweet/Green/}' | tac
cabbage
spinach
collard greens
corn salad
Green pepper
kale
And, for carrots:
$ tac file.txt | sed '2 s/.*/carrots/' | tac
cabbage
spinach
collard greens
corn salad
carrots
kale
How it works: Here, we use tac
to reverse the order of the lines. Observe:
$ tac file.txt
kale
Sweet pepper
corn salad
collard greens
spinach
cabbage
In this way, the second-to-last line becomes line number 2. Thus, we just simply tell sed to operate on line number 2. Afterward, we use tac
again to put the lines but in correct order.
How to fetch the 13th and the second last line from the standard output
You never know which line is "second to last" when reading a stream until you read the actual last line and the stream ends. The only possible way, is to always buffer the previous line, and when the stream ends, output the line from the buffer.
For example with sed
:
$ seq 20 | sed -n '13p;${x;p};h'
13
19
etc. with similar tools.
seq 20 | awk 'NR==13{print} {last=current; current=$0} END{print last}'
seq 20 | { n=1; while IFS= read -r line; do if ((n++ == 13)); then printf "%s\n" "$line"; fi; previous=$current; current=$line; done && printf "%s\n" "$previous"; }
But you can also just buffer the whole output and count the number of lines and output the second to last line....
# with a file
seq 20 > tempfile ; sed -n "13p;$(( $(wc -l < tempfile) - 1 ))p" file
# with memory
seq 20 | { buf=$(cat); sed -n "13p;$(( $(wc -l <<<"$buf") - 1 ))p" <<<"$buf"; }
Bash: grabbing the second line and last line of output (ls -lrS) only
Using awk
:
ls -lrS | awk 'NR==2 { print; } END { print; }'
It print
s when the line number NR
is 2 and again on the final line.
Note: As pointed out in the comments, $0
may or may not be available in an END
block depending on your awk
version.
How to only read the last line from a text file
Use tail
;)
line=$(tail -n 1 input_file)
echo $line
How do I read the Nth line of a file and print it to a new file?
Sed can help you.
Recall that sed will normally process all lines in a file AND print each line in the file.
You can turn off that feature, and have sed only print lines of interest by matching a pattern or line number.
So, to print the 2nd line of file 2, you can say
sed -n '2p' file2 > newFile2
To print the 2nd line and then stop processing add the q (for quit) command (you also need braces to group the 2 commands together), i.e.
sed -n '2{p;q;}' file2 > newFile2
(if you are processing large files, this can be quite a time saving).
To make that more general, you can change the number to a variable that will hold a number, i.e.
lineNo=3
sed -n "${lineNo}{p;q;}" file3 > newFile3
If you want all of your sliced lines to go into 1 file, then use the shells 'append-redirection', i.e.
for lineNo in 1 2 3 4 5 ; do
sed -n "${lineNo}{p;q;}" file${lineNo} >> aggregateFile
done
The other postings, with using the results of find ...
to drive your filelist, are an excellent approach.
I hope this helps.
Related Topics
Packaging Proprietary Software for Linux
Dma Cache Coherence Management
Use Sudo Inside Dockerfile (Alpine)
Bash Print Stderr Only, Not Stdout
How to Tail -F the Latest Log File with a Given Pattern
How to Recursively Search for Files with Certain Extensions
Bumping Version Numbers for New Releases in Associated Files (Documentation)
"Tput: No Value for $Term and No -T Specified " Error Logged by Cron Process
How to List the Files in a Zip Archive Without Decompressing It
Remove Occurrences of String in Text File
Ssh Command Execution Hangs, Although Interactive Shell Functions Fine
How to Replace Single Quotes with Another Character in Sed
What Is the Best Tool to Convert Common Video Formats to Flv on a Linux Cli
Start-Stop-Daemon Quoted Arguments Misinterpreted
Critical Timing in an Arm Linux Kernel Driver
How to Flush Cache of Hard-Disk and Flash-Disk (Or Filesystem) from Command Line