Replacing by using sed wit regexp - regex

Need to replace string in a file with regular expression.
My regexp is api.(dev[0-9]+\.)?side.com and I am using it with call:
sed "s/api.(dev[0-9]+\.)?side.com/$SERVER_HOST_VALUE/g"
But it didn't found any strings like "api.side.com" or "api.dev02.side.com". Regular expression worked for me and not worked only with "sed" command.
So how to use current regexp properly with sed?

Based on #fedorqui's and #hwnd's recommendation, use the -r option:
sed -re "s/api.(dev[0-9]+\.)?side.com/$SERVER_HOST_VALUE/g"
Note: If you use single quotes instead of double quotes, the variable $SERVER_HOST_VALUE won't be expanded.
Test
SERVER_HOST_VALUE="AWESOME"
tests=( "api.side.com" "api.dev05.side.com" )
for t in "${tests[#]}"; do
echo "$t" | sed -re "s/api.(dev[0-9]+\.)?side.com/$SERVER_HOST_VALUE/g"
done
Output
Note how the matches are replaced by $SERVER_HOST_VALUE:
AWESOME
AWESOME

Related

Why does this regex work in grep but not sed?

I have two regular expressions:
$ grep -E '\-\- .*$' *.sql
$ sed -E '\-\- .*$' *.sql
(I am trying to grep lines in sql files that have comments and remove lines in sql files that have comments)
The grep command works using this regex; however, the sed returns the following error:
sed: -e expression #1, char 7: unterminated address regex
What am I doing incorrectly with sed?
(The space after the two hyphens is required for sql comments if you are unfamiliar with MySql comments of this type)
You're trying to use:
sed -E '\-\- .*$' *.sql
Here sed command is not correct because you're not really telling sed to do something.
It should be:
sed -n '/-- /p' *.sql
and equivalent grep would be:
grep -- '-- ' *.sql
or even better with a fixed string search:
grep -F -- '-- ' *.sql
Using -- to separate pattern and arguments in grep command.
There is no need to escape - in a regex if it is outside bracket expression (or character class) i.e. [...].
Based on comments below it seems OP's intent is to remove commented section in all *.sql files that start with 2 hyphens.
You may use this sed for that:
sed -i 's/-- .*//g' *.sql
The problem here is not the regex, the problem is that sed requires a command. The equivalent of your grep would be:
sed -n '/\-\- .*$/p'
You suppress output for non-matching lines -n ... you search (wrap your regex in slashes) and you print p (after the last slash).
P.S.: As Anub pointed out, escaping the hyphens - inside the regex is unnecessary.
You are trying to use sed's \cregexpc syntax where with \-<...> you are telling sed the delimiter character you want use is a dash -, but you didn't terminate it where it should be: \-<...>- also add d command to delete those lines.
sed '\-\-\-.*$-d' infile
see man sed about that:
\cregexpc
Match lines matching the regular expression regexp. The c may be any character.
if default / was used this was not required so:
sed '/--.*$/d' infile
or simply:
sed '/^--/d' infile
and more accurately:
sed '/^[[:blank:]]*--/d' infile

Replace value using REGEX with Groovy and SED

I have an XML file that contains a "Description" property. I would like to replace the contents of that property with a different description. I am using a SED command within a Groovy script
<VisualElements Description="foo" Title="title"/>
I tried the following line, but it does not replace the value of the "Description" value with the string "bar".
def sedCommand = 'sed -i \'s/Description="([^"]*)"/Description="bar"/g\' package.appxmanifest' as String
Can someone tell me what is wrong with the above line?
Update: based on Wiktor Stribiżew's comment below, I have updated the command to reflect the latest error
You are using sed with a BRE regex (i.e. no -E or -r options), so your ( and ) are parsed as literal parentheses, not a grouping construct. Anyway, you are not using backreferences and replacing the whole match, there is no point keeping the parentheses at all:
def sedCommand = 'sed -i \'s/Description="[^"]*"/Description="bar"/g\' package.appxmanifest' as String
^^^^^
will work well.
If you need to use variables, see How do I use variables in a sed command?
The sed command will look as
#!/bin/bash
foo="hello"
echo '<VisualElements Description="foo" Title="title"/>' | \
sed 's/Description="[^"]*"/Description="'$foo'"/g'
See this demo.

Replace some dots(.) with commas(,) with RegEx and awk or sed

I want to replace dots with commas for some but not all matches:
hostname_metric (Index: 1) to hostname;metric (avg);22.04.2015 13:40:00;3.0000;22.04.2015 02:05:00;2.0000;22.04.2015 02:00:00;650.7000;2.2594;
The outcome should look like this:
hostname_metric (Index: 1) to hostname;metric (avg);22.04.2015 13:40:00;3,0000;22.04.2015 02:05:00;2,0000;22.04.2015 02:00:00;650,7000;2,2594;
I was able to identify the RegEx which should work to find the correct dots.
;[0-9]{1,}\.[0-9]{4}
But how can I replace them with a comma with awk or sed?
Thanks in advance!
Adding some capture groups to the regex in your question, you can use this sed one-liner:
sed -r 's/(;[0-9]{1,})\.([0-9]{4})/\1,\2/g' file
This matches and captures the part before and after the . and uses them in the replacement string.
On some versions of sed, you may need to use -E instead of -r to enable Extended Regular Expressions. If your version of sed doesn't understand either switch, you can use basic regular expressions and add a few escape characters:
sed 's/\(;[0-9]\{1,\}\)\.\([0-9]\{4\}\)/\1,\2/g' file
sed 's/\(;[0-9]\+\)\.\([0-9]\{4\}\)/\1,\2/g' should do the trick.

PCRE Regex to SED

I am trying to take PCRE regex and use it in SED, but I'm running into some issues. Please note that this question is representative of a bigger issue (how to convert PCRE regex to work with SED) so the question is not simply about the example below, but about how to use PCRE regex in SED regex as a whole.
This example is extracting an email address from a line, and replacing it with "[emailaddr]".
echo "My email is abc#example.com" | sed -e 's/[a-zA-Z0-9]+[#][a-zA-Z0-9]+[\.][A-Za-z]{2,4}/[emailaddr]/g'
I've tried the following replace regex:
([a-zA-Z0-9]+[#][a-zA-Z0-9]+[\.][A-Za-z]{2,4})
[a-zA-Z0-9]+[#][a-zA-Z0-9]+[\.][A-Za-z]{2,4}
([a-zA-Z0-9]+[#][a-zA-Z0-9]+[.][A-Za-z]{2,4})
[a-zA-Z0-9]+[#][a-zA-Z0-9]+[.][A-Za-z]{2,4}
I've tried changing the delimited of sed from s/find/replace/g to s|find|replace|g as outlined here (stack overflow: pcre regex to sed regex).
I am still not able to figure out how to use PCRE regex in SED, or how to convert PCRE regex to SED. Any help would be great.
Want PCRE (Perl Compatible Regular Expressions)? Why don't you use perl instead?
perl -pe 's/[a-zA-Z0-9]+[#][a-zA-Z0-9]+[\.][A-Za-z]{2,4}/[emailaddr]/g' \
<<< "My email is abc#example.com"
Output:
My email is [emailaddr]
Write output to a file with tee:
perl -pe 's/[a-zA-Z0-9]+[#][a-zA-Z0-9]+[\.][A-Za-z]{2,4}/[emailaddr]/g' \
<<< "My email is abc#example.com" | tee /path/to/file.txt > /dev/null
Use the -r flag enabling the use of extended regular expressions. ( -E instead of -r on OS X )
echo "My email is abc#example.com" | sed -r 's/[a-zA-Z0-9]+#[a-zA-Z0-9]+\.[A-Za-z]{2,4}/[emailaddr]/g'
Ideone Demo
GNU sed uses basic regular expressions or, with the -r flag, extended regular expressions.
Your regex as a POSIX basic regex (thanks mklement0):
[[:alnum:]]\{1,\}#[[:alnum:]]\{1,\}\.[[:alpha:]]\{2,4\}
Note that this expression will not match all email addresses (not by a long shot).
for multiline use the 0!
perl -0pe 's/search/replace/gms' file
Sometimes this might be helpful too as a work-around:
str=$(grep -Poh "pcre-pattern" file)
sed -i "s/$str/$something_else/" file
-o, --only-matching:
Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.

sed: cannot solve this regular expression

I'm trying to replace two strings in a php file using two sed commands, can't find where I'm wrong.
Want to transform from strings
setlocale(LC_ALL, $_COOKIE['lang']);
and
putenv("LANGUAGE=".$_COOKIE['lang']);
to the strings
setlocale(LC_ALL, $_COOKIE['lang'].'.utf8');
and
putenv("LANGUAGE=".$_COOKIE['lang'].'.utf8');
so far I've come to the following but does not work
sed -i "s/setlocale\(LC_ALL, \$_COOKIE\['lang'\]\);.*$/setlocale\(LC_ALL, \$_COOKIE\['lang'\]\.'\.utf-8'\)\;/" file.php
sed -i "s/putenv\('LANGUAGE='\.\$_COOKIE\['lang'\]\);.*$/putenv\('LANGUAGE='\.\$_COOKIE\['lang'\]\.'\.utf-8'\)\;/" file.php
I'm definitely not an expert in sed and regular expression, so go easy on me ok?
Try these two:
sed 's/setlocale.LC_ALL, ._COOKIE..lang...;/setlocale\(LC_ALL, $_COOKIE\['\''lang'\''\].'\''.utf8'\''\);/g' file.php
sed 's/putenv..LANGUAGE...._COOKIE..lang...;/putenv\("LANGUAGE=".$_COOKIE\['\''lang'\''].'\''.utf8'\'');/g' file.php
You should not escape the parentheses. There is no need to escape matching characters in the replacement part, either:
sed "s/setlocale(LC_ALL, \$_COOKIE\['lang'\]);.*$/setlocale(LC_ALL, \$_COOKIE['lang'].'.utf-8')\;/"
The putenv line contains double quotes, but your expressions searches for single quotes. Therefore, it cannot match.