How do I replace this text with quotation marks? - regex

I want to replace
$rcmail_config['default_host'] = '';
in /var/lib/roundcube/config/main.inc.php
with
$rcmail_config['default_host'] = 'localhost';
I've tried:
sed -i "s/$rcmail_config['default_host'] = '';/$rcmail_config['default_host'] = 'localhost';/g" /var/lib/roundcube/config/main.inc.php
and
sed -i s/$rcmail_config['default_host'] = '';/$rcmail_config['default_host'] = 'localhost';/g /var/lib/roundcube/config/main.inc.php
But it does not work.
What could I try next?

You need to escape the $ and [ symbols and also you don't need to repeat the same string in the replacement part. Instead of this, you may use capturing groups.
sed -i "s/\(\$rcmail_config\['default_host'\] = \)'';/\1'localhost';/g" file

Related

Sed substitution with Apex character

I'm trying to implement the following substitution
sed -i 's/$config['default_host'] = '';/$config['default_host'] = 'localhost';/' /etc/roundcube/config.inc.php
but it's not working.
What i want to do to is replace $config['default_host'] = ''; with $config['default_host'] = 'localhost'; inside the file /etc/roundcube/config.inc.php
Any ideas?
You should escape the special characters, because sed consider $ as a end of the character in a line
sed "s/\$config\['default_host'\] = '';/\$config['default_host'] = 'localhost';/" fileName
Using Grouping concept
sed "s/\(\$config\['default_host'\] = \)'';/\1'localhost';/" fileName
Output:
$config['default_host'] = 'localhost';

How do I replace a line with sed with /

Hello I currently have a file in this format:
This is a test file
location = /home/files
My question is how do I replace this line location = /home/files with this location = /home/documents/test_files?
When there's a "/" in the original string, or replacement string, we muse use "\" to escape "/". Alternatively you can use any character as substitution delimiter, such as "#"
$ cat sample.csv
This is a test file
location = /home/files
$ sed 's#/home/files#/home/documents/test_files#' sample.csv
This is a test file
location = /home/documents/test_files
Just choose a different delimiter:
sed 's-location = /home/files-location = /home/documents/test_files-' test.txt
sed 's~location = /home/files~location = /home/documents/test_files~' test.txt
Or escape the /:
sed 's/location = \/home\/files/location = \/home\/documents\/test_files/' test.txt

How to trim lines includes specific string with sed

I have separate files include path string for each like ;
path = /aaa/bbb/ccc.com/user#ccc.com/dddd/user#yahoo.com/
path = /aaa/bbb/ccc.com/user#ccc.com/dddd/user#hotmail.co.uk/
path = /aaa/bbb/ccc.com/user#ccc.com/dddd/user#abc.xxx.co.uk/
path = /aaa/bbb/ccc.com/user#ccc.com/dddd/user55#ccc.com/
what i want to trim lines like;
path = /aaa/bbb/ccc.com/user/dddd/.user#yahoo/
path = /aaa/bbb/ccc.com/user/dddd/.user#hotmail/
path = /aaa/bbb/ccc.com/user/dddd/.user#abc/
path = /aaa/bbb/ccc.com/user/dddd/.user55#ccc.com/
I am almost be able to achieve with below (all strings are in separate files but at the 15th line)
sed -r '15s!#[^/]+(/[^/]+/[^.#]+#[^.]+).*$!\1/!g' $file
however, i have an issue with dot part that cuts it as ;
path = /aaa/bbb/ccc.com/user/dddd/user55#ccc/
instead, it should have been;
path = /aaa/bbb/ccc.com/user/dddd/.user55#ccc/
Thanks in advance,
Using a pattern with three capture groups should do what you need. The first group will capture the portion behind the initial # (as a group we omit from the replacement), the second group will include the /dddd/ portion, and the third being the complete user#somewhere with a prepended .
's!(#.+\..+)(/.+/)(.+#.+)!\2.\3!g'
Depending on your version of bash you could use it like this:
sed -i.bak -r 's!(#.+\..+)(/.+/)(.+#.+)!\2.\3!g' $file
↳ (GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
sed -i bak -E 's!(#.+\..+)(/.+/)(.+#.+)!\2.\3!g' $file
↳ GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)
result:
path = /aaa/bbb/ccc.com/user/dddd/.user#yahoo.com/
path = /aaa/bbb/ccc.com/user/dddd/.user#hotmail.co.uk/
path = /aaa/bbb/ccc.com/user/dddd/.user#abc.xxx.co.uk/
path = /aaa/bbb/ccc.com/user/dddd/.user55#ccc.com/
It's a little unclear if you want to keep the full extension on the end of the last match; if not sed is probably not the best choice because it can't do look-ahead, look-behind assertions, nor toggle greedy in any straight-forward manner. In the case that's a deal breaker, you could use this pattern on one of many other avenues:
(#.+\..+)(/.+/)(.+#.+?)(\..*/)
result:
path = /aaa/bbb/ccc.com/user/dddd/.user#yahoo
path = /aaa/bbb/ccc.com/user/dddd/.user#hotmail
path = /aaa/bbb/ccc.com/user/dddd/.user#abc
path = /aaa/bbb/ccc.com/user/dddd/.user55#ccc
You would have to use two matches:
sed -E 's/(.*?\..*?)\/(.*?)#\1/\1\/\2/g'
Regex: (.*?\..*?)\/(.*?)#\1
Replacement: \1\/\2
Flags: g (Global)
Result:
path = /aaa/bbb/ccc.com/user/dddd/user#yahoo.com/
path = /aaa/bbb/ccc.com/user/dddd/user#hotmail.co.uk/
path = /aaa/bbb/ccc.com/user/dddd/user#abc.xxx.co.uk/
path = /aaa/bbb/ccc.com/user/dddd/user55#ccc.com/
sed -E 's/(\w+#\w+)[\w\.]*/\1/g'
Regex: (\w+#\w+)[\w\.]*
Replacement: \1
Flags: g (Global)
Result:
path = /aaa/bbb/ccc.com/user/dddd/user#yahoo/
path = /aaa/bbb/ccc.com/user/dddd/user#hotmail/
path = /aaa/bbb/ccc.com/user/dddd/user#abc/
path = /aaa/bbb/ccc.com/user/dddd/user55#ccc/
If the -E switch is not available on your version of sed, then you might have to use perl.
Example:
perl -pe 's/(.*?\..*?)\/(.*?)#\1/\1\/\2/g' -i filename.ext
If I try this in bash, I get the following result:
root#home [~]# echo "path = /aaa/bbb/ccc.com/user#ccc.com/dddd/user55/" | sed -E 's/(.*?\..*?)\/(.*?)#\1/\1\/\2/g'
path = /aaa/bbb/ccc.com/user/dddd/user55/
root#home [~]# echo "path = /aaa/bbb/ccc.com/user/dddd/user55/" | sed -E 's/(\w+#\w+)[\w\.]*/\1/g'
path = /aaa/bbb/ccc.com/user/dddd/user55/

Replace end of varying string

I have tried dozens of various sed options but haven't found a combination that works yet. I am trying to turn:
test(3) = var
other(8) = var
test(13) = var
...
into:
test(3) = newvar
other(8) = var
test(13) = newvar
...
The problem I'm encountering is the varying value in the parentheses. I want to edit after the value, to prevent having to catch it and assign it. I tried the following, thinking I could use .* as a wildcard inside the parentheses, but I can't seem to get it to work.
sed -n "s/\(test(.*\)\s+\w+/\1) = newstuff/g" file.txt
You can use this sed command:
sed -i.bak 's/^\([^=]* *= *\).*$/\1newvar/' file
This will match RHS string (from start until = is found) and that is replaced by newvar
If you want to use a shell variable then use double quotes:
NEWVAR="something"
sed -i.bak "s/^\([^=]* *= *\).*$/\1$NEWVAR/" file
UPDATE: To change only lines starting with test:
sed -i.bak "s/^\( *test *[^=]* *= *\).*$/\1$NEWVAR/" file

Trying to match a string and add it to the replacement

I am trying to add a string to the end of a line using sed and regex.
I have the following string:
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
and im trying to add to the end of it the string:
exec,system,shell_exec,passthru,
My attempt is as follows:
sed -ie 's/disable_functions = .*[a-zA-z,]$/disable_functions = $1exec,system,shell_exec,passthru,/gI' /etc/php5/apache2/php.ini
It seems to just add $1 to the string disable_functions = $1exec,system,shell_exec,passthru,
Where am I going wrong?
Try that :
sed '/^disable_functions/s/$/exec,system,shell_exec,passthru,/' /etc/php5/apache2/php.ini
If the output seems OK, then add -i switch to modify the file.
$ here, mean end of line.
Your original command is missing the capture group which sets the value of \1 (not $1):
sed -ie 's/disable_functions = \(.*[a-zA-z,])\$/disable_functions = \1exec,system,shell_exec,passthru,/gI' /etc/php5/apache2/php.ini
But as sputnick points out, you simply need to find the appropriate line and append the desired text; there's no need to match the old values and reinsert them.