Replace a specific token with the contents of the file (using bash - script)

I have a file containing text and the words INSERT_HERE1 and INSERT_HERE2 . I would like to replace these words with the contents of file1.txt and file2.txt respectively.

I suspect sed or awk might disable it, but I basically never used them.

+4
source share
7 answers

If you're fine with Perl, you can do:

 $ cat FILE1 this is file1 $ cat FILE2 this is file2 $ cat file foo INSERT_HERE1 bar INSERT_HERE2 baz $ perl -ne 's/^INSERT_HERE(\d+)\s+$/`cat FILE$1`/e;print' file foo this is file1 bar this is file2 baz $ 
+3
source

Sed has a built-in command to read files. The commands you want look something like this:

 $ sed -e '/INSERT_HERE1/ { r FILE1 d }' -e '/INSERT_HERE2/ { r FILE2 d }' < file 

This will lead to the conclusion

 foo this is file1 bar this is file2 baz 

The r command reads the file, and the d command deletes the line with the INSERT_HERE tags. You need to use curly braces, as sed commands and multi-line input, as sed commands must run on their own line, and depending on your shell, you may need \ at the end of lines to avoid premature execution. If this is something that you would use a lot, you can just put the command in a file and use sed -f to run it.

+8
source

This is not tested, but will be pretty close to what you need:

 sed -e "s/INSERT_HERE1/`cat file1.txt`/" -e "s/INSERT_HERE2/`cat file2.txt`/" <file >file.out 

It will not handle the file with a slash in it correctly, so you may need to tweak it a bit.

I would recommend Perl instead. Something like that:

 #!/usr/bin/perl -w my $f1 = `cat file1.txt`; my $f2 = `cat file2.txt`; while (<>) { chomp; s/INSERT_HERE1/$f1/; s/INSERT_HERE2/$f2/; print "$_\n"; } 

This suggests that INSERT_HERE1 and INSERT_HERE2 can only appear once per line and that file1.txt does not contain the text INSERT_HERE2 (although this would not be difficult to fix). Use the following:

 ./script <file >file.out 
+1
source

This is suitable for small replacement files that can be replaced many times:

 awk 'BEGIN { while ((getline line < ARGV[1]) > 0) {file1 = file1 nl line; nl = "\n"}; close (ARGV[1]); nl = ""; while ((getline line < ARGV[2]) > 0) {file2 = file2 nl line; nl = "\n"}; close (ARGV[2]); ARGV[1] = ""; ARGV[2] = "" } { gsub("token1", file1); gsub("token2", file2); print }' file1.txt file2.txt mainfile.txt 

You might want to add some new translation lines here too, depending on how you want your output to look.

+1
source

Easy to do with Bash. If you need this to be a POSIX shell, let me know:

 #!/bin/bash IFS= # Needed to prevent the shell from interpreting the newlines f1=$(< /path/to/file1.txt) f2=$(< /path/to/file2.txt) while read line; do if [[ "$line" == "INSERT_HERE1" ]]; then echo "$f1" elif [[ "$line" == "INSERT_HERE2" ]]; then echo "$f2" else echo "$line" fi done < /path/to/input/file 
+1
source

This snippet replaces any section specified in the top array. E.g. here

 <!--insert.txt--> 

with the contents of "insert.txt"

 #!/bin/bash replace[1]=\<!--insert.txt--\> ; file[1]=insert.txt replace[2]=\<!--insert2.txt--\> ; file[2]=insert2.txt replacelength=${#replace[@]} cat blank.txt > tmp.txt for i in $(seq 1 ${replacelength}) do echo Replacing ${file[i]} ... sed -e "/${replace[i]}/r ${file[i]}" -e "/${replace[i]}/d" tmp.txt > tmp_2.txt mv tmp_2.txt tmp.txt done mv tmp.txt file.txt 

If you are not afraid of .zip files, you can try this example if it is online: http://ablage.stabentheiner.de/2013-04-16_contentreplace.zip

0
source

I would use perl instead of replacing - i.ext option

 perl -pi.bak -e 's|INSERT_HERE1|`cat FILE1`|ge; s|INSERT_HERE2|`cat FILE2`|ge;' myfile 

Then use diff myfile.bak myfile to check:

0
source

All Articles