Operating System - HP-UX
1827595 Members
2826 Online
109966 Solutions
New Discussion

replace a string with "/" in a variable

 
SOLVED
Go to solution
Billa-User
Regular Advisor

replace a string with "/" in a variable

hello,

i use often sed to replace a string, but
here it is not a good way, other options ?

what's the best way to replace a string with "/"

input for example: /dev/vgold_fs/config
new output : /dev/vgneu

it work's good with
echo /dev/vgold_fs/config |sed "sX/dev/vgold_fs/configX/dev/vgneuXg"

But when you have a X in the string, then you get with:

echo "/dev/vgold_fs/configX" | sed "sX/dev/vgold_fsX/dev/vgneuXg"

sed: Function sX/dev/vgold_fs/configXXX/dev/vgneuXg cannot be parsed.

i have to prepare the input string like
"\\\\\/dev/vgold_fs/configX" ?

not so good

regards



11 REPLIES 11
James R. Ferguson
Acclaimed Contributor
Solution

Re: replace a string with "/" in a variable

Hi:

Change your delimiters:

# X=/dev/vgold_fs/config
# echo $X|sed -e 's|/dev/vgold_fs/config|/dev/vgneu|'
/dev/vgneu

Regards!

...JRF...
Billa-User
Regular Advisor

Re: replace a string with "/" in a variable

great, great.

maybe you have also an improvement for "awk" and escape-ing like this:

it is only an example (but used for parse commands like "bdf", "lvdisplay" )

OK (because i escape )

X="/dev/vgold_fs/config"
X_AWK=$( echo ${X} | sed "s|/|\\\\\/|g" )
echo "/dev/vgold_fs/config feld2 feld3" | awk '$1 ~ /^'${X_AWK}'$/ {print $1}'
/dev/vgold_fs/config

NOT-OK:

X="/dev/vgold_fs/config"
echo "/dev/vgold_fs/config feld2 feld3" | awk '$1 ~ /^'${X}'$/ {print $1}'

syntax error The source line is 1.
The error context is
$1 ~ /^/dev/vgold_fs/config$/ {print >>> $1} <<<
awk: Quitting
The source line is 1.

Dennis Handly
Acclaimed Contributor

Re: replace a string with "/" in a variable

>maybe you have also an improvement for "awk" and escape-ing like this:

What are you really trying to do? It seems you are looking for an exact match for the first field. Why not:
echo "/dev/vgold_fs/config feld2 feld3" |
awk -v select="$X" '$1 == select {print $1}'

>X_AWK=$( echo ${X} | sed "s|/|\\\\\/|g" )

Better to use single quotes and then the number of "\"s are predictable:
X_AWK=$( echo "${X}" | sed -e 's|/|\\/|g' )

>echo "/dev/vgold_fs/config feld2 feld3" | awk '$1 ~ /^'${X_AWK}'$/ {print $1}'

If you really want a pattern match, better go with variables than constant regular expression that has "//":
echo "/dev/vgold_fs/config feld2 feld3" |
awk -v pat="$X" '$1 ~ ("^" pat "$") {print $1}'

(The "^" and "$" anchors could be included in the original $X.)
Billa-User
Regular Advisor

Re: replace a string with "/" in a variable

>What are you really trying to do? It seems you are looking for an exact match for the > first field. Why not:

if want to search with a shell variable , which include "/" or "\" with "awk" in field 1 for example.

example: fs=/tmp

then i want search for "${fs}" with command "bdf" and work with "awk"

like:
bdf | awk "$NF ~ ... { print ....

regards.

sorry, i explain it not very good :-((
Dennis Handly
Acclaimed Contributor

Re: replace a string with "/" in a variable

>if want to search with a shell variable, which include "/" or "\" with "awk" in field 1 for example.

I as asking if you wanted an exact match (first example: ==) by a pattern match (ERE) (the last example: ~).

>then I want search for "${fs}" with command "bdf" and work with "awk"

awk "$NF ~ ...

It is much easier to put the pattern in a variable. Then you don't have to worry about the "/" delimiters.

You can also use the match function.
James R. Ferguson
Acclaimed Contributor

Re: replace a string with "/" in a variable

Hi (again):

> if want to search with a shell variable , which include "/" or "\" with "awk" in field 1 for example.

> example: fs=/tmp

First, I would avoid the temptation to use a variable name, that if upper-cased would become an 'awk' reserved variable name -- FS.

Consider these two ways of matching:

# |awk -v FSYS=/ho '$NF~FSYS'
/home

...which is probably *not* what you want.

# bdf | awk -v FSYS=/ho '$NF==FSYS {print $NF}'

...returns nothing since the comparison for equality fails.

# bdf | awk -v FSYS=/home '$NF==FSYS {print $NF}'
/home

...which is what you appear to want.

Regards!

....JRF...

...and:

# bdf |
~/Sandbox jrf $ df -h | awk -v FSYS=/home '$NF==FSYS'
map auto_home 0Bi 0Bi 0Bi 100% /home
~/Sandbox jrf $ df -h | awk -v FSYS=/ho '$NF==FSYS'
~/Sandbox jrf $
Billa-User
Regular Advisor

Re: replace a string with "/" in a variable

for a example,
i have more filesystems like /home1, /home2
then :

exact match for "/home" , right ?
bdf | awk -v FSYS=/home '$NF==FSYS {print $NF}'
matches all filesystems
bdf | awk -v FSYS=/home '$NF ~ FSYS {print $NF}'

i can use "~" with ERE like FSYS[0-9]
bdf | awk -v FSYS=/home '$NF ~ FSYS[0-9] {print $NF}'

in another usage, when i have to search in a file where
FS is or then i use following command:

awk -v text=search ' BEGIN { FS = "[ \t]*|[ \t]+" }
$NF ~ search {print $NF}' /tmp/text



Dennis Handly
Acclaimed Contributor

Re: replace a string with "/" in a variable

>I have more filesystems like /home1, /home2 then:
>exact match for "/home", right?
>... | awk -v FSYS=/home '$NF==FSYS

Yes.

>matches all filesystems
... | awk -v FSYS=/home '$NF ~ FSYS

Yes, those /home* ones.

>I can use "~" with ERE like FSYS[0-9]
... | awk -v FSYS=/home '$NF ~ FSYS[0-9]

Not like that. Either:
... | awk -v FSYS='/home[0-9]' '$NF ~ FSYS
Or:
... | awk -v FSYS=/home '$NF ~ (FSYS "[0-9]")

>when I have to search in a file where FS is or then I use following command:
awk -v text=search 'BEGIN { FS = "[ \t]*|[ \t]+" }
$NF ~ search {print $NF}' /tmp/text

Don't do that. The default is already tab or blank but ignoring leading tab/blanks.
(Not sure why you are using both "*" and "+" in your ERE? Only "+" should be used for one or more.)
And you could use -F on the command line to set FS.
Billa-User
Regular Advisor

Re: replace a string with "/" in a variable

great, great, great.

one more example:
i have more filesystems like /home1, /home2, /home33

then i match /home1, /home2 like:
... awk -v FSYS="/home[0-9]$" '$NF ~ FSYS { print $0 }'
or
... awk -v FSYS=/home '$NF ~ (FSYS"[0-9]""$") { print $0 }'
/dev/vg00/lvol4 1048576 757648 288720 72% /home1
/dev/vg00/lvol4 1048576 757648 288720 72% /home2

then i match /home1, /home2, /home33 like:
... awk -v FSYS="/home[0-9]+$" '$NF ~ FSYS { print $0 }'
or
....awk -v FSYS=/home '$NF ~ (FSYS"[0-9]+""$") { print $0 }'
/dev/vg00/lvol4 1048576 757648 288720 72% /home1
/dev/vg00/lvol4 1048576 757648 288720 72% /home2
/dev/vg00/lvol4 1048576 757648 288720 72% /home33

OK , my syntax ? it works, like i want and you show me :-)
James R. Ferguson
Acclaimed Contributor

Re: replace a string with "/" in a variable

Hi (again):

> i have more filesystems like /home1, /home2, /home33

> ... awk -v FSYS="/home[0-9]$" '$NF ~ FSYS { print $0 }'

This prevents you from matching things like '/home11'.

> ... awk -v FSYS=/home '$NF ~ (FSYS"[0-9]""$") { print $0 }'

This is uselessly cluttered.

> ... awk -v FSYS="/home[0-9]+$" '$NF ~ FSYS { print $0 }'

This is fine.

> ....awk -v FSYS=/home '$NF ~ (FSYS"[0-9]+""$") { print $0 }'

Again, this is cluttered with extraneous double quotes. Though it will match the FSYS variable with one or more digits before the end.

When you can, compare for equality as opposed to matching a regular expression. The former will be faster. This is why I suggested:

# bdf | awk -v FSYS=/home '$NF==FSYS {print $NF}'

ALSO:

# ...awk -v FSYS="/home[0-9]+$" '$NF ~ FSYS { print $0 }'

... *may* match what you want and it may *not*. Consider:

# echo "/Users/home11"| awk -v FSYS="/home[0-9]+$" '$NF ~ FSYS { print $0 }'
/Users/home11

...which is probably not what you intended to match. This can be corrected by adding the '^' anchor:

# echo "/Users/home11"| awk -v FSYS="^/home[0-9]+$" '$NF ~ FSYS { print $0 }'

...or testing for simple equality:

Regards!

...JRF...


Dennis Handly
Acclaimed Contributor

Re: replace a string with "/" in a variable

>... awk -v FSYS=/home '$NF ~ (FSYS"[0-9]""$") { print $0 }'

No need to separate the "$" from the rest:
'$NF ~ (FSYS "[0-9]$") { print $0 }'

>then I match /home1, /home2, /home33 like:
... awk -v FSYS="/home[0-9]+$" '$NF ~ FSYS

Yes.

>... awk -v FSYS=/home '$NF ~ (FSYS"[0-9]+""$") { print $0 }'

Same here:
... awk -v FSYS=/home '$NF ~ (FSYS "[0-9]+$") { print $0 }'