1

I have an question about how to insert a string into the second to last line of a file.

For example:

$ cat diff_a.txt
students
teacher
mike
john

$ cat diff_b.txt
python
bash shell
Java

Expected Result should be:

$ cat diff_b.txt
python
bash shell
mike
Java

If I use the following command, it will append string "mike" into the last line of diff_b.txt

$ grep mike diff_a.txt >> diff_b.txt
$ cat diff_b.txt
python
bash shell
Java
mike

Question:

How should I put "mike" into second to last line of diff_b.txt ?
binbjz
  • 821
  • 11
  • 15
  • 1
    Are you asking how to insert the string `'mike'` into diff_b.txt or how to insert whatever string is at the 2nd-last line of diff_a.txt into diff_b.txt? The rest of your question sounds like you want the former but then if so why are you showing us diff_a.txt at all? Why are you doing `grep mike diff_a.txt` to get `mike` instead of just `echo mike`? Whatever it is you need please [edit] your question to clarify. – Ed Morton Aug 03 '17 at 13:06

6 Answers6

6

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 \
Mago
  • 183
  • 1
  • 12
2

To read the output from any command, such as grep mike diff_a.txt, into the second-to-last line of diff_b.txt:

ed -s diff_b.txt <<< $'$-1r !grep mike diff_a.txt\nwq'

This puts ed into script mode, then feeds commands to it as if they were typed as input:

  • $' ... ' - a quoted string of:
  • $-1r - on the $ last line minus 1, r read from:
  • ! grep ... - the shell command grep ...
  • \n - end the r command with a carriage return
  • wq - write (save the file) and quit ed

This is much simpler for your example, if you already know what text you want to insert:

ed -s diff_b.txt <<< $'$-1a\nmike\n.\nwq'

Here we use the a append command (ended by a carriage return), enter the mike text (ended by a carriage return), then exit a append mode with a . (ended by a carriage return), then save and exit.

Jeff Schaller
  • 2,352
  • 5
  • 23
  • 38
1

I have a python solution. Read the lines from the file into a list using readlines and then inserting a value.

import re
import sys

file_name = sys.argv[1]
fp = open(file_name)
lines = fp.readlines()
your_output = lines.insert(len(lines)-1,"insert text") # you can also use sys.argv[2] if you want two inputs, first is file_name (also accepts file path), second can be your insert text
Billy Ferguson
  • 1,429
  • 11
  • 23
1

Kind of a hacky solution, but you can use negative line counts with head to get all but the last line, insert your new line, then use tail to grab just the last line of the original file. You'll have to redirect the output to a temporary file first, then overwrite your original file.

 ( head -n -1 diff_b.txt
 echo "mike"
 tail -n 1 diff_b.txt ) > tmp.txt
 mv tmp.txt diff_b.txt
eduffy
  • 39,140
  • 13
  • 95
  • 92
1

grep a line from a file and insert to the second to last position into another file

if you don't have a special chars...

$ tac file2 | sed "2i$(grep mike file1)" | tac

python
bash shell
mike
Java
karakfa
  • 66,216
  • 7
  • 41
  • 56
0

Create test file

echo -e 'Hi\n123\nBye' > test.txt

enter image description here

Proximo
  • 6,235
  • 11
  • 49
  • 67