Issue
sed "/^.*#location/n;/.*location/i 0000" myfile
Find a location that does not start with a comment and insert 0000 in front of it the first time it matches.
What did I do wrong?
I 4 hours try some answers from google, try combine, but nothing changed.
For example this: sed to insert on first match only
I try add like this:
sed "0,/^.*#location/n;/.*location/i 0000" myfile
or this:
sed "/^.*#location/n;0,/.*location/i 0000" myfile
and this:
sed "/^.*#location/n;/.*location/i 0000\n&/0" myfile
Input:
server {
#location /api/graphql {
# modsecurity off;
# proxy_pass http://10.1.0.4;
#}
location 123 {
proxy_pass 123;
}
location / {
modsecurity off;
proxy_pass http://10.1.0.4;
}
}
Output:
server {
#location /api/graphql {
# modsecurity off;
# proxy_pass http://10.1.0.4;
#}
0000
location 123 {
proxy_pass 123;
}
location / {
modsecurity off;
proxy_pass http://10.1.0.4;
}
}
Input:
server {
#location /api/graphql {
# modsecurity off;
# proxy_pass http://10.1.0.4;
#}
location 73347347 {
proxy_pass 123;
}
location 123 {
proxy_pass 123;
}
location / {
modsecurity off;
proxy_pass http://10.1.0.4;
}
}
Output:
server {
#location /api/graphql {
# modsecurity off;
# proxy_pass http://10.1.0.4;
#}
0000
location 73347347 {
proxy_pass 123;
}
location 123 {
proxy_pass 123;
}
location / {
modsecurity off;
proxy_pass http://10.1.0.4;
}
}
Solution
Using GNU awk for the 3rd arg to match()
:
$ awk '!done && match($0,/^([[:space:]]*)location/,a){print a[1] "0000" ORS; done=1} 1' file
server {
#location /api/graphql {
# modsecurity off;
# proxy_pass http://10.1.0.4;
#}
0000
location 123 {
proxy_pass 123;
}
location / {
modsecurity off;
proxy_pass http://10.1.0.4;
}
}
or using any POSIX awk:
$ awk '!done && match($0,/^([[:space:]]*)location/){new=$0; sub(/[^[:space:]].*/,"0000",new); print new ORS; done=1} 1' fileserver {
#location /api/graphql {
# modsecurity off;
# proxy_pass http://10.1.0.4;
#}
0000
location 123 {
proxy_pass 123;
}
location / {
modsecurity off;
proxy_pass http://10.1.0.4;
}
}
Regarding "What did I do wrong?" - sed's great for doing s/old/new/ on individual lines but for anything else, just use awk for clarity, simplicty, etc.
Answered By - Ed Morton Answer Checked By - Dawn Plyler (WPSolving Volunteer)