-1

My aim is to add " double quote when ever the below word are coming in file

VGHIER_TSV_WB798
CBVGHIER_TSV_WB798

here

sed -i 's/"VGHIER_TSV_WB798"./VGHIER_TSV_WB798./g'

is used to remove the double quote if any allready prasent and

sed -i 's/VGHIER_TSV_WB798./"VGHIER_TSV_WB798"./g'

to add the quote but the issue I am getting when we got the CBVGHIER_TSV_WB798 it is repalced as CB"VGHIER_TSV_WB798", which I don't want I have separate sed statement to repalce the secodn word

sed -i 's/CBVGHIER_TSV_WB798./"CBVGHIER_TSV_WB798"./g'

could you please help me how to achive the above requiement.

ilkkachu
  • 138,973
ram
  • 137
  • 1
    So the problem is when this string appears in a longer word -- please could you show us some example content from the input file? Are these words the only thing on the line? Also, which version of sed are you using? – JigglyNaga Feb 08 '18 at 11:03
  • @JigglyNaga - isn't -i a GNU thing? – Guy Feb 08 '18 at 11:17
  • 1
    @Guy It's non-standard, but often implemented (although with varying semantics). See e.g. https://unix.stackexchange.com/questions/401905/bsd-sed-vs-gnu-sed-and-i – Kusalananda Feb 08 '18 at 11:33

2 Answers2

2

If your sed supports EREs, you could add the CB as an optional part of the pattern to match. This would replace both of those:

sed -E 's/(CB)?VGHIER_etc/"\1VGHIER_etc"/g'  test

Or, if your sed supports \< and \> for start and end of word, use those:

sed 's/\<VGHIER_etc\>/"VGHIER_etc"/g'  test

Also, you have a trailing dot . in the pattern, it will match any character, and it will be replaced as part of the string. The dot in the replacement will put a literal dot back. s/foo./"foo"./ changes food to "foo".

ilkkachu
  • 138,973
1

I think you want to add a leading prefix to your search string. If the word that you are trying to replace will always be preceded by a space:

sed -i 's/ VGHIER_TSV_WB798\./ "VGHIER_TSV_WB798"./g'

More generically, you can use the regex grouping [[:space:]] to cover cases of leading spaces or tabs etc (see man isspace for complete list).

sed -i 's/\([[:space:]]\)VGHIER_TSV_WB798\./\1"VGHIER_TSV_WB798"./g'

In that case, we needed to add an additional complexity by creating a regex grouping using the escaped parentheses, and use a back reference \1 to be sure not to lose the exact character when performing the replacement. There is also a regex class [[:punct:]] for punctuation characters, in case the word is preceded sometimes by one of them. See man isspace for a complete detailed list of what each regex character class covers.

Here's a more complex example solution to cover the case of possible punctuation prefixes:

sed -i 's/\([[:space:]]\|[[:punct:]]\)VGHIER_TSV_WB798\./\1"VGHIER_TSV_WB798"./g'

This makes use of the regex directive | (escaped with a backslash for sed) to indicate an alternative.

Finally, if the word will always be the first item on the line, use the ^ regex to require that:

sed -i 's/^VGHIER_TSV_WB798\./"VGHIER_TSV_WB798"./g'

And yes, for any of the above, you could have "group"ed and "back-referenced" your string:

sed -i 's/^\(VGHIER_TSV_WB798\)\./"\1"./g'
sed -i 's/\([[:space:]]\|[[:punct:]]\)\(VGHIER_TSV_WB798\)\./\1"\2"./g'
user1404316
  • 3,078