Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert multiple lines stored in a variable using sed in a file

Ubuntu 14.04

I want to insert few lines stored in a source file into a target file. I'll read all those lines in a variable $var i.e. if I do echo "${var}" then it'll give me the following output -- which I want to add in my apache config file at a given line.

My exact source file (aka ${var})contents are:

        ## apppush proxying - get content from live site --##
        RewriteRule /apppush/hreflang/(.*) http://localhost:8081/hreflang.php?u=https://www.company.com/apppush/hreflang/$1 [P,L]

        RewriteCond /www/retaildb/companycom/us/branches/somebranch/us/%{SCRIPT_FILENAME} -d [OR]
        RewriteCond /www/retaildb/companycom/us/branches/somebranch/us/%{SCRIPT_FILENAME} -f
        RewriteRule ^/apppush/retail/(.*) /www/retaildb/companycom/us/branches/somebranch/us/%{SCRIPT_FILENAME} [L]

        ## Search/GIGA apppush rewrite
        RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} !-f
        RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} !-d
        RewriteRule ^/apppush/(.*)/search/(.*) /www/giga/%{SCRIPT_FILENAME} [L]

        RewriteRule /apppush/(.*) https://www.company.com/apppush/$1 [P]
        ## END apppush Rewrites --##

To do the above operation using a simple example, I tried the following commands, which is giving me an error.

For ex: I want to add ${var} which contains some values (3 lines total) into giga.txt file at line #3.

$ cat giga.txt
1
2
3
4
5
$ var="$(echo -e "333-444-555\n444-555-666\n555-666-777")"
$ echo "${var}"
333-444-555
444-555-666
555-666-777
gigauser@re-gigadev-s03-dev-2-32-3-rno:~/SVN_WS/repos/shenziconf$
$ sed -i "3i${var}" giga.txt
sed: -e expression #1, char 18: unknown command: `-'

I was expecting the output in giga.txt file as:

1
2
333-444-555
444-555-666
555-666-777
3
4
5

The end goal is to insert source file contents at line #3 in giga.txt (Target file / apache config file).

There are other ways to do this using a program to pick line# 1st-to-N, add source file contents, then line#s N+1 -to- EndOfFile to get the desired output but I trying to see if sed or awk can do this --OR--

PS For ex: The following command can successfully do similar operation (i.e. insert lines taken from a source file at a given location of the target file) BUT I'm looking how to do it via using a $variable (if possible).

sed -i "3r sourcefile.txt" targetfile.txt

like image 458
AKS Avatar asked Aug 08 '17 21:08

AKS


People also ask

How can I add multiple lines to a file?

The simplest way to append multiple lines to a file is to use the echo and printf command. Let us start with echo. Echo is a command used to output a string or multiple strings as arguments.

Can you use sed on a variable?

The sed command is a common Linux command-line text processing utility. It's pretty convenient to process text files using this command. However, sometimes, the text we want the sed command to process is not in a file. Instead, it can be a literal string or saved in a shell variable.

How do I add a new line using sed?

Insert a line in a File You have to use the “-i” option with the “sed” command to insert the new line permanently in the file if the matching pattern exists in the file.


1 Answers

Since in the end you want to read from files and not a variable, you can use the r command directly: it reads a file and inserts it after the current line. So if you have giga.txt with

1
2
3
4
5

and source.txt with

333-444-555
444-555-666
555-666-777

you can use this command:

$ sed '2r source.txt' giga.txt            
1
2
333-444-555
444-555-666
555-666-777
3
4
5

Notice that I've changed the line number to 2, as r appends after the line, whereas i inserts before the line.


If you really want to insert from a variable, you have to prepare it a bit: i requires that newlines are escaped with \, so if you do this

var=$(sed '$!s/$/\\/' source.txt)

you'll have a variable that looks as follows:

$ echo "$var"
333-444-555\
444-555-666\
555-666-777

and you can use this sed command:

$ sed "3i$var" giga.txt 
1
2
333-444-555
444-555-666
555-666-777
3
4
5

If you have GNU sed, you can combine these two approaches (hat tip Sundeep's comment): GNU sed can read standard input from the special file /dev/stdin, so you can use

sed '2r /dev/stdin' giga.txt <<< "$var"

or, if your shell doesn't support here strings like Bash does,

echo "$var" | sed '2r /dev/stdin' giga.txt

where $var doesn't need to have its newlines escaped.

like image 141
Benjamin W. Avatar answered Nov 15 '22 05:11

Benjamin W.