简体   繁体   中英

How can i replace text with sed by matching previous line

I have this file:

user_default:
    resource: "@UserDefaultBundle/Controller/"
    type:     annotation
    prefix:   /
Other_default:
    resource: "@PeopDefaultBundle/Controller/"
    type:     annotation
    prefix:   /

I want to replace the prefix under user_default to /user

I know how I can replace in single line, but I don't know how to check the previous lines.

This might work for you (GNU sed):

sed -r '/^\S/{h;b};G;/^user_default:/M{s/(prefix:\s*\S).*/\1user/};P;d' /file

This copies a section header into the hold space and thereafter appends it to lines within that section. If the line contains both user_default: and prefix: it does the required substitution.

NB It uses the multi-line switch M to check that the section header begins with the required label.

EDIT: Missed the obvious!:

sed -r '/^user_default:/,/^\s*prefix:/{s/\(prefix:\s*).*/\1\/user/}' file

Basically it's not that easy with sed, but it's doable ( see this answer and modify to suit to your needs if sed is the only option). I'd recommend to use awk for this job, like:

awk '/^user_default:/ { print ; ud=1 ; next}
     /^ +resource:/ && ud==1 {print gensub("@UserDefaultBundle","/user",1) ; ud=0 ; next }
     { print }' INPUTFILE

This AWK solution should work, change the variables accordingly.

awk -v p="prefix:" -v x="user_default:" '{
{!/^[[:space:]]/ && NF=1 && a=$NF}
{if ((a==x) && ($0~p))
sub(/\//,"/user")}
}1' filename

Using sed

sed -r '/user_default:/{:a;N;/prefix/!{/\n\S/!ba};s!(prefix:\s*).*!\1/user!}' file

This command will avoid to apply the change to wrong session, if "prefix" is not exist in user_default session.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM