Search a pattern in file and replace another pattern in the same line

谁都会走 提交于 2020-06-08 17:23:08

问题


I would like to search for a pattern in bunch of source files. The pattern should act as a marker. If the pattern is found, I would like to process that line by performing a substitution of another string

For example:

Private const String myTestString = @"VAL15"; // STRING—REPLACE-VAL##

Here, I want to search my source file for pattern STRING—REPLACE-VAL and then replace VAL15 with VAL20 in same.

Output:

private const String myTestString = @"VAL20"; // STRING—REPLACE-VAL##

Tried below command but not working as expected.

sed -i  '/,STRING—REPLACE-VAL##/ {; s/,VAL15,/,VAL20,/;}' myTestFile.cpp

Question: Is it possible to search for STRING—REPLACE-VAL## and then search for matching pattern @"VAL??" in same line and replace 15 by 20.

sed supports search & replacing the same pattern very easily but not sure if sed supports to search pattern but replace another string in the matching line?

Any help would be appreciated. Thanks in advance.


回答1:


You were very close :

sed -i '/STRING—REPLACE-VAL##/{s/VAL15/VAL20/}' myTestFile.cpp

In your original you were trying to replace ",VAL15," but this string is not in the line (the commas). Furthermore, the same occurs for your search string ",STRING—REPLACE-VAL##".

It also occured to me that the first hyphen between STRING and REPLACE is an em-dash and not a standard -, maybe this is another problem. Make sure that the string is exactly the same. If you are not sure about the dashes, you could use

sed -i '/STRING.REPLACE.VAL##/{s/VAL15/VAL20/}' myTestFile.cpp

and to answer your question, yes you can try to do multiple matches in the following way:

sed:

sed -i '/STRING.REPLACE.VAL##/{ /@"VAL/ { s/VAL15/VAL20/ } }' myTestFile.cpp

awk:

awk '/STRING.REPLACE.VAL##/&&/@"VAL/{sub("VAL15","VAL20")}1'  myTestFile.cpp



回答2:


The search pattern in the attempt includes many superfluous/erronious commas -- and that is the reason that the match was failing. Patterns and searches are delimited by default with the / character. (Unless you have a specific reason to do otherwise it is a good idea to stick with / for readability.)

One thing to be careful of is to make sure that your word is exactly matched... and that VAL152 (for example) is not matched. You can enclose VAL15 within \< and \> to match the word boundary.

Also, wrapping parentheses are not required after the match pattern.

sed -i '/STRING—REPLACE-VAL##/ s/\<VAL15\>/VAL20/' myTestFile.cpp

@kvantour noted that you specified a special em dash character in the match that is non-ascii & suggested ways to work around this -- but we can also use a trick to exactly match what you want and make that aspect stand out more (note: sh/bash assumed as the shell -- note the careful use of quoting).

sed -i "/STRING$(printf '\342\200\224')REPLACE-VAL##/ s/\<VAL15\>/VAL20/" myTestFile.cpp

Or to match hyphen and em dash in both places:

emdash=$(printf '\342\200\224')
sed -i "/STRING[-$emdash]REPLACE[-$emdash]VAL##/ s/\<VAL15\>/VAL20/" myTestFile.cpp

We can expand on this further on this to include the en dash as well -- left as an exercise for the reader. To help with that exercise, here is how I was able to decode your em dash char:

echo '—' | od -c



回答3:


With GNU sed you could just do

sed -i '/STRING—REPLACE-VAL##/s/VAL15/VAL20/' myTestFile.cpp


来源:https://stackoverflow.com/questions/49432797/search-a-pattern-in-file-and-replace-another-pattern-in-the-same-line

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