20

I'm working on a bash script that will split the contents of a text document depending on the data in the line.

If the contents of the original file were along the lines of

01 line
01 line
02 line
02 line

How can I insert into line 3 of this file using bash to result in

01 line
01 line
text to insert
02 line
02 line

I'm hoping to do this using a heredoc or something similar in my script

#!/bin/bash

vim -e -s ./file.txt <<- HEREDOC
    :3 | startinsert | "text to insert\n"
    :update
    :quit
HEREDOC

The above doesn't work of course but any recommendations that I could implement into this bash script?

1

5 Answers 5

22

You can use the POSIX tool ex by line number:

ex a.txt <<eof
3 insert
Sunday
.
xit
eof

Or string match:

ex a.txt <<eof
/Monday/ insert
Sunday
.
xit
eof

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html

0
15

sed would be a traditional choice (GNU sed probably has an easier form than this).

$ cat input
01 line
01 line
02 line
02 line
$ sed '2a\
text to insert
' < input
01 line
01 line
text to insert
02 line
02 line
$ 

Or, being extremely traditional, ed (bonus! in-place edit without the unportable sed -i form).

$ (echo 2; echo a; echo text to insert; echo .; echo wq) | ed input
32
01 line
47
$ cat input
01 line
01 line
text to insert
02 line
02 line
$ 

(This has nothing to do with bash.)

2
  • 2
    added bonux replace echo text to insert by cat file-to-insert.txt
    – Archemar
    Commented Mar 22, 2016 at 15:06
  • 1
    At least with bash, instead of all those echos, you could use printf '%s\n' 2 a 'text to insert' . wq
    – evilsoup
    Commented Mar 22, 2016 at 22:58
13
$ awk 'NR==3{print "text to insert"}1' a.txt
01 line
01 line
text to insert
02 line
02 line
1
9

How about something like:

head -n 2 ./file.txt > newfile.txt
echo "text to insert" >> newfile.txt
tail -n +3 ./file.txt >> newfile.txt
mv newfile.txt file.txt
3
  • 2
    Strange but interesting idea +1 Commented Jun 7, 2019 at 20:27
  • head -n 5 ./pom.xml > pomnew.xml echo "<packaging>war</packaging>" >> pomnew.xml tail -n +6 ./pom.xml >> pomnew.xml mv pomnew.xml pom.xml Commented Dec 5, 2022 at 5:03
  • You may compact this like this: (head -2 file.txt; echo row three ; tail -3 file.txt) > newfile.txt (using Gnu Linux tools). Commented Feb 23, 2023 at 21:32
1

Try the following:

Your original file

$ cat <<'EOF' > file.txt
01 line
01 line
02 line
02 line
EOF

insert into line 3 using a heredoc.

$ cat <<'EOF' | sed -i "3r /dev/stdin" file.txt
text to insert
EOF

you get this result

$ cat file.txt
01 line
01 line
text to insert
02 line
02 line

UPDATED: Following the comment of @Kusalananda

2
  • 5
    Brevity is acceptable, but fuller explanations are better. Also note that the user gives a specific example use case in their question. It would benefit your answer (and your duplicated answer here) to actually use the user's sample documents.
    – Kusalananda
    Commented Feb 23, 2023 at 14:03
  • 1
    @Kusalananda: Thanks for your comment. I've updated my answer.
    – wolfrevo
    Commented Feb 23, 2023 at 16:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .