简体   繁体   中英

how to replace part of a string using sed

echo "/home/repository/tags/1.9.1/1.9.1.8/core" | sed "s/HELP/XXX/g"

I would like some HELP in replacing what is in between tags and core with let's say XXX. So my desired output would be /home/repository/tags/XXX/core.

The string is a directory path, where /home/repository/tags are the only constant parts. The path is always six levels deep. So it may not always be between tags and core.

echo "/home/repository/whatever/1.9.1/1.9.1.8/core/and/more/junk"   \
| sed 's@\(/[^/]*/[^/]*/[^/]*\)/[^/]*/[^/]*@\1/XXX@'

yields ...

/home/repository/whatever/XXX/core/and/more/junk

By using repetition quantifiers, you can easily adjust where your replacement is made:

echo "/home/repository/tags/1.9.1/1.9.1.8/core" | \
    sed -r 's|(/([^/]+/){3})([^/]+/){2}(.*)|\1XXX/\4|'
  • 3 represents how many components to keep at the beginning
  • 2 represents how many to replace

You could even use variables:

$ dirs='/one/two/three/four/five/six/seven/eight'
$ for keep in {0..3}; do for replace in {0..3}; do echo "$dirs" | \
    sed -r "s|(/([^/]+/){$keep})([^/]+/){$replace}(.*)|\1XXX/\4|"; done; done
/XXX/one/two/three/four/five/six/seven/eight
/XXX/two/three/four/five/six/seven/eight
/XXX/three/four/five/six/seven/eight
/XXX/four/five/six/seven/eight
/one/XXX/two/three/four/five/six/seven/eight
/one/XXX/three/four/five/six/seven/eight
/one/XXX/four/five/six/seven/eight
/one/XXX/five/six/seven/eight
/one/two/XXX/three/four/five/six/seven/eight
/one/two/XXX/four/five/six/seven/eight
/one/two/XXX/five/six/seven/eight
/one/two/XXX/six/seven/eight
/one/two/three/XXX/four/five/six/seven/eight
/one/two/three/XXX/five/six/seven/eight
/one/two/three/XXX/six/seven/eight
/one/two/three/XXX/seven/eight

If your directory is always 6 levels deep, this works (remember to escape the round brackets):

echo "/home/repository/tags/1.9.1/1.9.1.8/core" | 
sed 's/\(\/home\/repository\/tags\/\).*\/.*\(\/.*\)/\1XXX\2/'

produces:

/home/repository/tags/XXX/core

Here, spare yourself some regex agony:

echo "/home/repository/tags/1.9.1/1.9.1.8/core" | sed 's@/home/repository/tags/.*/\(.\+\)$@/home/repository/tags/XXX/\1@'

No need to explicitly match the components if all you're really trying to do is strip out everything between tags/ and the last component. Note that I used + not * , so the component must be nonempty. That'll guard against having a trailing slash.

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