I\'m trying to write a bash script, which will do the following:
I use sed like this and it worked as a charm
sed -i -e '/pattern/r filetoinsert' filetobeinserted
What it does is insert the 'filetoinsert' into 'filetobeinserted' after the line with the specified pattern
Take care to choose a unique pattern, not sure how it will work with a duplicate patterns, I assume it will do it just of the first one
You need spaces around the =~
operator. Compare:
[[ foo=~bar ]]
[[ foo =~ bar ]]
This is because the first expression essentially evaluates as "Is this string empty?"
Also, the OP code uses small tilde rather than tilde.
Even so, you can easily get rid of the inner loop. Just replace the whole while read -r line2
bit with cat -- "$second_filename"
.
Your last echo $line
is only correct if the file does not end in a newline character (standard with *nix tools). Instead, you should use while read -r line || [[ $line ~= '' ]]
. This works with or without newline at the end.
Also, Use More Quotes™.
Using awk works as well.
To insert before the ###marker### line :
// for each <line> of second_file.txt :
// if <line> matches regexp ###marker###, outputs first_file.txt.
// **without any condition :** print <line>
awk '/###marker###/ { system ( "cat first_file.txt" ) } \
{ print; } \' second_file.txt
To insert after the ###marker###line :
// for each <line> of second_file.txt :
// **without any condition :** print <line>
// if <line> matches regexp ###marker###, outputs first_file.txt.
awk '{ print; } \
/###marker###/ { system ( "cat first_file.txt" ) } \' second_file.txt
To replace the ###marker### line :
// for each <line> of second_file.txt :
// if <line> matches regexp ###marker###, outputs first_file.txt.
// **else**, print <line>
awk '/###marker###/ { system ( "cat first_file.txt" ) } \
!/###marker###/ { print; }' second_file.txt
If you want to do in-place replacement, use a temp file for being sure the pipe doesn't start before awk has read the entire file; add :
> second_file.txt.new
mv second_file.txt{.new,}
// (like "mv second_file.txt.new second_file.txt", but shorter to type !)
If you want replacement inside of the line, (replacing just the pattern and keeping the rest of the line), a similar solution should be achievable with sed instead of awk.
sed
can do that without loops. Use its r
command:
sed -e '/pattern/rFILE1' FILE2
Test session:
$ cd -- "$(mktemp -d)"
$ printf '%s\n' 'nuts' 'bolts' > first_file.txt
$ printf '%s\n' 'foo' 'bar' 'baz' > second_file.txt
$ sed -e '/bar/r./first_file.txt' second_file.txt
foo
bar
nuts
bolts
baz
This should work:
perl -lne 'BEGIN{open(A,"first_file.txt");@f=<A>;}print;if(/2222/){print @f}' second_file.txt
Tested:
> cat temp
111111
1111
11
1
> cat temp2
122221
2222
22
2
> perl -lne 'BEGIN{open(A,"temp");@f=<A>;}print;if(/2222/){print @f}' temp2
122221
111111
1111
11
1
2222
111111
1111
11
1
22
2
>