I'm trying to write a script that replaces text in a text file between two patterns "opt/" and "/". An example of the data in the file is:
daw9udiwa9diuoawdj098awd89a0909w opt/TEXTTOREPLACE/app-data/version.txt
wdalkwhjf8aufwaoif98fawfojaw98f8 opt/TEXTTOREPLACE/app-data/package.txt
awdhaw9d8yawdf8uaw9f8uwafhiuhawf opt/TEXTTOREPLACE/bin/somefile/somefile
wdalkwhjf8aufwaoif98fawfojaw98f8 opt/TEXTTOREPLACE/bin/someapp/somefile
I've looked at using the 'sed' command, but the pattern matching is confusing me.
I have tried:
sed -e 's!\/[^\/]*\/!\/CHANGE TO ME\/!'
This works - but I would like to add in the "opt" at the beginning to minimise errors
So I tried the following with no luck
sed -e 's!opt\/[^opt\/]*\/!opt\/CHANGE TO ME\/!'
I will be using a $VAR to replace text so for example
VAR=CHANGED
sed -e 's!opt\/[^opt\/]*\/!opt\/$VAR\/!'
output:
daw9udiwa9diuoawdj098awd89a0909w opt/CHANGED/app-data/version.txt
wdalkwhjf8aufwaoif98fawfojaw98f8 opt/CHANGED/app-data/package.txt
awdhaw9d8yawdf8uaw9f8uwafhiuhawf opt/CHANGED/bin/somefile/somefile
wdalkwhjf8aufwaoif98fawfojaw98f8 opt/CHANGED/bin/someapp/somefile
help appreciated. Thanks
CodePudding user response:
A few issues with the current sed
code:
- to expand OS variables the
sed
script must be wrapped in double quotes - the use of
!
as a delimiter may cause issues with some shells and/or shell configurations (eg,!
is a common shorthand for accessing the command line history) - escaping the
/
is only needed when the/
also serves as thesed
script delimiter (ie, no need to escape/
if using a different delimiter)
One sed
idea that addresses these issues:
sed -e "s|opt/[^/]*|opt/$VAR|" input.txt
Where:
opt/[^/]*
- match on the stringopt/
plus all characters that are not a\
opt/$VAR
- replace with the stringopt/
plus the contents of the OSVAR
variable
This generates:
daw9udiwa9diuoawdj098awd89a0909w opt/CHANGED/app-data/version.txt
wdalkwhjf8aufwaoif98fawfojaw98f8 opt/CHANGED/app-data/package.txt
awdhaw9d8yawdf8uaw9f8uwafhiuhawf opt/CHANGED/bin/somefile/somefile
wdalkwhjf8aufwaoif98fawfojaw98f8 opt/CHANGED/bin/someapp/somefile
CodePudding user response:
If you are open to using awk
rather than sed
, the following may work for you:
$ awk -v rep="CHANGED" -F/ 'BEGIN{OFS="/"} {$2=rep; print}' file1
daw9udiwa9diuoawdj098awd89a0909w opt/CHANGED/app-data/version.txt
wdalkwhjf8aufwaoif98fawfojaw98f8 opt/CHANGED/app-data/package.txt
awdhaw9d8yawdf8uaw9f8uwafhiuhawf opt/CHANGED/bin/somefile/somefile
wdalkwhjf8aufwaoif98fawfojaw98f8 opt/CHANGED/bin/someapp/somefile
Split each line on the forward slash character and replace the second field with your desired replacement text. Then format the output with the output field separator (OFS) set as a forward slash.