Sed substitution with Apex character - regex

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';

Related

SED one liner to uncomment and replace first occurrence of a pattern

I have this settings.conf file in linux defined as follows:
Section A
first-setting = value
# second-setting = off
third-setting = value
Section B
first-setting = value
# second-setting = off
third-setting = value
I would like to uncomment # second-setting = off of Section A only (first occurrence), and set the value to on.
So far, I have this:
cat settings.conf | sed '/^# second.*/ {s/^#//;s/off/on/}'
Any tips?
Is this what you had in mind?
sed '0,/#/s/#\(.*\) off/\1 on/' settings.conf
Or if your on osx with non-gnu sed:
sed '1,/#/s/#\(.*\) off/\1 on/' settings.conf
sed -e '1,/^Section B/s/# second-setting = off/ section-setting = on/' settings.conf

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 do I replace this text with quotation marks?

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

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