In the following example:
echo "manoeuvre man track" | awk -v replace="man" '{ gsub(replace, ""); print }'
I get this result:
oeuvre track
I would like it to replace text only when it finds the whole word, so as a result, I would get:
manoeuvre track
(only the word man was removed)
--
I tried this with word boundaries (\b and \y), but I cannot understand how to apply them here.
I made it work with a for loop, but I thought maybe there is a more straightforward way using gsub?
I only have AWK and don't have gAWK.
CodePudding user response:
"Vanilla" awk is not a good fit for this task. I'd use perl:
$ echo "manoeuvre man track" |perl -pe 's/\bman\b//g'
manoeuvre track
or if you want to pass "man" as a parameter:
$ echo "manoeuvre man track" |perl -spe 's/\b${word}\b//g' -- -word=man
manoeuvre track
One last point: if you want the "word" treated as a literal string, use the \Q...\E
regex markers:
$ echo "manoeuvre man m.n trackm.n" |perl -spe 's/\b${word}\b//g' -- -word=m.n
manoeuvre trackm.n
$ echo "manoeuvre man m.n trackm.n" |perl -spe 's/\b\Q${word}\E\b//g' -- -word=m.n
manoeuvre man trackm.n
CodePudding user response:
This may be what you're trying to do, using any awk, assuming you want the first full-field literal string match:
$ echo "manoeuvre man track" |
awk -v replace="man" '
s=index(" "$0" "," "replace" ") {
$0 = substr($0,1,s-2) substr($0,s length(replace))
}
{ print }
'
manoeuvre track
or this if you want to do a full-field regexp match for all fields:
$ echo "manoeuvre man track" |
awk -v replace="man" '
{
$0=" "$0" "
gsub(" "replace" "," ")
gsub(/^ | $/,"",$0)
print
}
'
manoeuvre track
There are lots of other possibilities...
CodePudding user response:
You can use the following with GNU awk
:
awk -v replace="man" '{gsub("\\<"replace"\\>", "")}1'
See the online demo:
#!/bin/bash
s="manoeuvre man track"
awk -v replace="man" '{gsub("\\<"replace"\\>", "")}1' <<< "$s"
# => manoeuvre track
NOTE:
- Word boundaries here are
\<
and\>
, and to use a literal\
char in theawk
command, it needs doubling replace
is a variable containing just word chars, so it is OK to use\<
and\>
word boundaries to wrap this value to match as a whole word (it would be more complicated if it contained non-word chars)- To create a pattern from a variable, you need to concatenate the values, here, it is done with
"\\<"replace"\\>"
. - Note that
print
is replaced with1
in the code above.