Reputation: 3038
I would like to use sed
(I think?) to replace a pattern with file contents.
Hello <<CODE>>
Goodbye.
Anonymous person,
I am very nice.
Hello Anonymous person,
I am very nice.
Goodbye.
Right now, I am using this command:
sed "/<<CODE>>/{r file2
:a;n;ba}" file1 | \
sed "s/<<CODE>>//g" > \
file3
But this outputs:
Hello
Anonymous person,
I am very nice.
Goodbye.
(note the newline after Hello
)
file2
may contain all sorts of things: brackets, newlines, quotes, ...)Upvotes: 4
Views: 1987
Reputation: 2761
You could do simply with:
awk '{gsub("<<CODE>>", filetwo)}1' filetwo="$(<file2)" file1
Upvotes: 1
Reputation: 784918
Much simpler to use awk:
awk 'FNR==NR{s=(!s)?$0:s RS $0;next} /<<CODE>>/{sub(/<<CODE>>/, s)} 1' file2 file1
Hello Anonymous person,
I am very nice.
Goodbye.
Explanation:
FNR==NR
- Execute this block for first file in input i.e. file2
s=(!s)?$0:s RS $0
- Concatenate whole file content in string s
next
- Read next line until EOF
on first file/<<CODE>>/
- If a line with <<CODE>>
is found execute that blocksub(/<<CODE>>/, s)
- Replace <<CODE>>
with string s
(data of file2
)1
- print the outputEDIT: Non-regex way:
awk 'FNR==NR{s=(!s)?$0:s RS $0; next}
i=index($0, "<<CODE>>"){$0=substr($0, 1, i-1) s substr($0, i+8)} 1' file2 file1
Upvotes: 3
Reputation: 6333
not too bad in Perl
:
cat file1 | perl -e "open FH, qq(file2); \$f2=join '', <FH>; chomp \$f2; map {s/<<CODE>>/\$f2/g; print \$_} <STDIN>" > file3
(maybe i am not the best perl coder)
it's straight-forward. read the whole file2 in, substitute it, then print.
Upvotes: 1
Reputation: 955
I am thinking about a solution where we use Bash to evaluate a cat
process outside of the single quotes delimitating the sed
script, but unfortunately the following doesn't work as soon as your file2
contains a newline:
sed 's/<<CODE>>/'"$(cat file2)"'/' file1
It accepts spaces in file2
, but not newlines, as you can see in the following piece of code that works well, whatever the content of file2
:
sed 's/<<CODE>>/'"$(cat file2 | tr -d '\n')"'/' file1
But, obviously, this modifies the content of the file before inclusion, which is simply bad. :-(
So if you want to play, you can first tr
the newlines to some weird unexpectable character, and translate those back after sed
has worked on its script:
sed 's/<<CODE>>/'"$(cat file2 | tr '\n' '\3')"'/' file1 | tr '\3' '\n'
Upvotes: 0
Reputation: 3260
The awk
though it might be harder to read, is probably the right way to go.
Just for comparison sake, here's a ruby version
ruby -ne 'BEGIN{@body=File.open("file2").read}; puts gsub(/<<CODE>>/,@body);' < file1
Upvotes: 1