Sed, is it possible to match everything between two chars?
In a script that I have to use there is a bug. The script has to replace the value of
#define MAPPING
,
The line containing the bug is the one below:
sed -i -e "s/#define MAPPING \"\"/#define MAPPING \"$string\"/1" file.hpp
Since in file.hpp
MAPPING is defined as:
#define MAPPING ""
the script works, but if I try to call the script again and MAPPING was already redefined, now sed
won't match #define MAPPING "" and thus not override anything.
I'm not a sed expert, and with a quick search couldn't find the way to let it match
#define MAPPING "<everything>"
.
Is it possible to achieve this?
CodePudding user response:
This is does you want:
sed -Ei 's/(#define MAPPING ")[^"]*(")/\1'"$string\2/" file.hpp
[^"]*
means zero or more non double quote characters.- I used back references instead of repeating the same text, it's up to you.
1
at the end of your example means replace the first occurence. However this is the default, so it can be removed.- Be aware: if
$string
contains sequences like&
,\5
, or\\
, they won't be passed literally, and can even cause an error. Also, C escapes like\t
for tab are expanded by many sed implementations (so you'll end up with a literal tab in the file, instead of\t
).
For what it's worth, this sed does the same thing, but is more accomodating of varied whitespace:
sed -Ei 's/(^[[:space:]]*#[[:space:]]*define[[:space:]] MAPPING[[:space:]] ")[^"]*(")/\1'"$string\2/" file.hpp
CodePudding user response:
You can also try:
sed -i -e "s/#define MAPPING \".*\"/#define MAPPING \"$string\"/1" file.hpp
The dot means anything can go here and the star means at least 0 times so .*
accepts any sequence of characters, including an empty string.