问题
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