sed replace positional match of unknown string divided by user-defined separator

瘦欲@ 提交于 2021-01-28 20:41:27

问题


Want to rename the (known) 3th folder within a (unknown) file path from a string, when positioned on 3th level while separator is /

Need a one-liner explicitly for sed. Because i later want use it for tar --transform=EXPRESSION

string="/db/foo/db/bar/db/folder"
echo -e "$string" | sed 's,db,databases,'

sed replace "db" only on 3th level

expected result

/db/foo/databases/bar/db/folder

回答1:


You could use a capturing group to capture /db/foo/ and then match db. Then use use the first caputring group in the replacement using \1:

string="/db/foo/db/bar/db/folder"
echo -e "$string" | sed 's,^\(/[^/]*/[^/]*/\)db,\1databases,'

About the pattern

  • ^ Start of string
  • \( Start capture group
    • /[^/]*/[^/]*/ Match the first 2 parts using a negated character class
  • \) Close capture group
  • db Match literally

That will give you

/db/foo/databases/bar/db/folder



回答2:


If awk is also an option for this task:

$ awk 'BEGIN{FS=OFS="/"} $4=="db"{$4="database"} 1' <<<'/db/foo/db/bar/db/folder'
/db/foo/database/bar/db/folder
  • FS = OFS = "/" assign / to both input and output field separators,
  • $4 == "db" { $4 = "database }" if fourth field is db, make it database,
  • 1 print the record.



回答3:


Here is a pure bash way to get this done by setting IFS=/ without calling any external utility:

string="/db/foo/db/bar/db/folder"
string=$(IFS=/; read -a arr <<< "$string"; arr[3]='databases'; echo "${arr[*]}")
echo "$string"

/db/foo/databases/bar/db/folder


来源:https://stackoverflow.com/questions/55343129/sed-replace-positional-match-of-unknown-string-divided-by-user-defined-separator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!