Adding text to a file 2 lines before the last pattern match
up vote
1
down vote
favorite
I need to add a the multi line string in TEXT
into myfile.txt
where it last find the text # My Search
.
If it was a regular pattern replace then sed
with i
would do the trick. However I don't know how to go 2 lines above the match in sed
.
Example, myfile.txt
:
text1
text2
#
# My Search
#
text4
text5
#
# My Search
#
text6
TEXT
looks like:
TEXT="
[my search]
home=/var/home
string=random
"
myfile.txt
should look at the end:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
text-processing awk sed
add a comment |
up vote
1
down vote
favorite
I need to add a the multi line string in TEXT
into myfile.txt
where it last find the text # My Search
.
If it was a regular pattern replace then sed
with i
would do the trick. However I don't know how to go 2 lines above the match in sed
.
Example, myfile.txt
:
text1
text2
#
# My Search
#
text4
text5
#
# My Search
#
text6
TEXT
looks like:
TEXT="
[my search]
home=/var/home
string=random
"
myfile.txt
should look at the end:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
text-processing awk sed
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I need to add a the multi line string in TEXT
into myfile.txt
where it last find the text # My Search
.
If it was a regular pattern replace then sed
with i
would do the trick. However I don't know how to go 2 lines above the match in sed
.
Example, myfile.txt
:
text1
text2
#
# My Search
#
text4
text5
#
# My Search
#
text6
TEXT
looks like:
TEXT="
[my search]
home=/var/home
string=random
"
myfile.txt
should look at the end:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
text-processing awk sed
I need to add a the multi line string in TEXT
into myfile.txt
where it last find the text # My Search
.
If it was a regular pattern replace then sed
with i
would do the trick. However I don't know how to go 2 lines above the match in sed
.
Example, myfile.txt
:
text1
text2
#
# My Search
#
text4
text5
#
# My Search
#
text6
TEXT
looks like:
TEXT="
[my search]
home=/var/home
string=random
"
myfile.txt
should look at the end:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
text-processing awk sed
text-processing awk sed
edited 2 days ago
don_crissti
48.7k15129157
48.7k15129157
asked 2 days ago
Nir
43221020
43221020
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
0
down vote
accepted
Use grep -n
to extract the line number, then use it in a sed address to insert the text, which needs to be properly quoted, i.e. there must be a backslash before each newline:
line=$(grep -n '# My Search' myfile.txt | tail -n1 | cut -f1 -d:)
((--line))
text=${TEXT//$'n'/$'\n'}
text=${text%$'\n'}$'n'
sed "$line i \
$text" myfile.txt
add a comment |
up vote
0
down vote
tac
+ bash
(variable substitution) + GNU sed
approach:
txt_reversed=$(echo "$TEXT" | tac)
tac myfile.txt
| sed -e "N;N;N; s~#n# My Searchn#~&${txt_reversed//$'n'/\n}n~" | tac
The output:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
add a comment |
up vote
0
down vote
The easiest way to do this in one go is to use a tool that can search backward, ed
is one of them. Ideally you would have the text saved in a file (e.g. insert.txt
) and insert the file content two lines before the last occurrence of PATTERN
so you could run:
ed -s infile <<IN
.t.
?PATTERN?-2r insert.txt
$d
,p
q
IN
It finds the last occurrence of PATTERN
, goes up another 2
lines and r
eads in insert.txt
. It then prints the content of the buffer via ,p
. Replace that with w
if you want to edit the file in-place.
With other tools that can't search backward a two-pass is the way to go: 1st pass - get the line number and 2nd pass - insert the text content after line NR-2
or before line NR-1
. For text saved in a variable I favor awk
over other tools that rely on regex (the latter require pre-processing the text to be inserted so as to escape any special characters: there are several ones that need escaping, not just the newline, depending on the technique used):
export TEXT
awk 'NR==FNR{if ($0 ~ /PATTERN/){c=NR};next}
{if (FNR==(c-1)){print ENVIRON["TEXT"]}};1' infile infile
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
Use grep -n
to extract the line number, then use it in a sed address to insert the text, which needs to be properly quoted, i.e. there must be a backslash before each newline:
line=$(grep -n '# My Search' myfile.txt | tail -n1 | cut -f1 -d:)
((--line))
text=${TEXT//$'n'/$'\n'}
text=${text%$'\n'}$'n'
sed "$line i \
$text" myfile.txt
add a comment |
up vote
0
down vote
accepted
Use grep -n
to extract the line number, then use it in a sed address to insert the text, which needs to be properly quoted, i.e. there must be a backslash before each newline:
line=$(grep -n '# My Search' myfile.txt | tail -n1 | cut -f1 -d:)
((--line))
text=${TEXT//$'n'/$'\n'}
text=${text%$'\n'}$'n'
sed "$line i \
$text" myfile.txt
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
Use grep -n
to extract the line number, then use it in a sed address to insert the text, which needs to be properly quoted, i.e. there must be a backslash before each newline:
line=$(grep -n '# My Search' myfile.txt | tail -n1 | cut -f1 -d:)
((--line))
text=${TEXT//$'n'/$'\n'}
text=${text%$'\n'}$'n'
sed "$line i \
$text" myfile.txt
Use grep -n
to extract the line number, then use it in a sed address to insert the text, which needs to be properly quoted, i.e. there must be a backslash before each newline:
line=$(grep -n '# My Search' myfile.txt | tail -n1 | cut -f1 -d:)
((--line))
text=${TEXT//$'n'/$'\n'}
text=${text%$'\n'}$'n'
sed "$line i \
$text" myfile.txt
answered 2 days ago
choroba
25.8k44470
25.8k44470
add a comment |
add a comment |
up vote
0
down vote
tac
+ bash
(variable substitution) + GNU sed
approach:
txt_reversed=$(echo "$TEXT" | tac)
tac myfile.txt
| sed -e "N;N;N; s~#n# My Searchn#~&${txt_reversed//$'n'/\n}n~" | tac
The output:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
add a comment |
up vote
0
down vote
tac
+ bash
(variable substitution) + GNU sed
approach:
txt_reversed=$(echo "$TEXT" | tac)
tac myfile.txt
| sed -e "N;N;N; s~#n# My Searchn#~&${txt_reversed//$'n'/\n}n~" | tac
The output:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
add a comment |
up vote
0
down vote
up vote
0
down vote
tac
+ bash
(variable substitution) + GNU sed
approach:
txt_reversed=$(echo "$TEXT" | tac)
tac myfile.txt
| sed -e "N;N;N; s~#n# My Searchn#~&${txt_reversed//$'n'/\n}n~" | tac
The output:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
tac
+ bash
(variable substitution) + GNU sed
approach:
txt_reversed=$(echo "$TEXT" | tac)
tac myfile.txt
| sed -e "N;N;N; s~#n# My Searchn#~&${txt_reversed//$'n'/\n}n~" | tac
The output:
text1
text2
#
# My Search
#
text4
text5
[my search]
home=/var/home
string=random
#
# My Search
#
text6
answered 2 days ago
RomanPerekhrest
22.6k12246
22.6k12246
add a comment |
add a comment |
up vote
0
down vote
The easiest way to do this in one go is to use a tool that can search backward, ed
is one of them. Ideally you would have the text saved in a file (e.g. insert.txt
) and insert the file content two lines before the last occurrence of PATTERN
so you could run:
ed -s infile <<IN
.t.
?PATTERN?-2r insert.txt
$d
,p
q
IN
It finds the last occurrence of PATTERN
, goes up another 2
lines and r
eads in insert.txt
. It then prints the content of the buffer via ,p
. Replace that with w
if you want to edit the file in-place.
With other tools that can't search backward a two-pass is the way to go: 1st pass - get the line number and 2nd pass - insert the text content after line NR-2
or before line NR-1
. For text saved in a variable I favor awk
over other tools that rely on regex (the latter require pre-processing the text to be inserted so as to escape any special characters: there are several ones that need escaping, not just the newline, depending on the technique used):
export TEXT
awk 'NR==FNR{if ($0 ~ /PATTERN/){c=NR};next}
{if (FNR==(c-1)){print ENVIRON["TEXT"]}};1' infile infile
add a comment |
up vote
0
down vote
The easiest way to do this in one go is to use a tool that can search backward, ed
is one of them. Ideally you would have the text saved in a file (e.g. insert.txt
) and insert the file content two lines before the last occurrence of PATTERN
so you could run:
ed -s infile <<IN
.t.
?PATTERN?-2r insert.txt
$d
,p
q
IN
It finds the last occurrence of PATTERN
, goes up another 2
lines and r
eads in insert.txt
. It then prints the content of the buffer via ,p
. Replace that with w
if you want to edit the file in-place.
With other tools that can't search backward a two-pass is the way to go: 1st pass - get the line number and 2nd pass - insert the text content after line NR-2
or before line NR-1
. For text saved in a variable I favor awk
over other tools that rely on regex (the latter require pre-processing the text to be inserted so as to escape any special characters: there are several ones that need escaping, not just the newline, depending on the technique used):
export TEXT
awk 'NR==FNR{if ($0 ~ /PATTERN/){c=NR};next}
{if (FNR==(c-1)){print ENVIRON["TEXT"]}};1' infile infile
add a comment |
up vote
0
down vote
up vote
0
down vote
The easiest way to do this in one go is to use a tool that can search backward, ed
is one of them. Ideally you would have the text saved in a file (e.g. insert.txt
) and insert the file content two lines before the last occurrence of PATTERN
so you could run:
ed -s infile <<IN
.t.
?PATTERN?-2r insert.txt
$d
,p
q
IN
It finds the last occurrence of PATTERN
, goes up another 2
lines and r
eads in insert.txt
. It then prints the content of the buffer via ,p
. Replace that with w
if you want to edit the file in-place.
With other tools that can't search backward a two-pass is the way to go: 1st pass - get the line number and 2nd pass - insert the text content after line NR-2
or before line NR-1
. For text saved in a variable I favor awk
over other tools that rely on regex (the latter require pre-processing the text to be inserted so as to escape any special characters: there are several ones that need escaping, not just the newline, depending on the technique used):
export TEXT
awk 'NR==FNR{if ($0 ~ /PATTERN/){c=NR};next}
{if (FNR==(c-1)){print ENVIRON["TEXT"]}};1' infile infile
The easiest way to do this in one go is to use a tool that can search backward, ed
is one of them. Ideally you would have the text saved in a file (e.g. insert.txt
) and insert the file content two lines before the last occurrence of PATTERN
so you could run:
ed -s infile <<IN
.t.
?PATTERN?-2r insert.txt
$d
,p
q
IN
It finds the last occurrence of PATTERN
, goes up another 2
lines and r
eads in insert.txt
. It then prints the content of the buffer via ,p
. Replace that with w
if you want to edit the file in-place.
With other tools that can't search backward a two-pass is the way to go: 1st pass - get the line number and 2nd pass - insert the text content after line NR-2
or before line NR-1
. For text saved in a variable I favor awk
over other tools that rely on regex (the latter require pre-processing the text to be inserted so as to escape any special characters: there are several ones that need escaping, not just the newline, depending on the technique used):
export TEXT
awk 'NR==FNR{if ($0 ~ /PATTERN/){c=NR};next}
{if (FNR==(c-1)){print ENVIRON["TEXT"]}};1' infile infile
answered 2 days ago
don_crissti
48.7k15129157
48.7k15129157
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f483150%2fadding-text-to-a-file-2-lines-before-the-last-pattern-match%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown