shell script find and replace in file - string

I have a file postmaster.log, in which I need to find pattern and change its value
Pattern I need to find is
MaxValue=3 #this could be any value not just 3
I need to change its value to
MaxValue=0
Issue is there are also patterns like
"MaxValueSet=3" and "MaxValue is currently low"
Which are also getting replaced.I only has to change MaxValue=3 to MaxValue=0
I tried using sed
sed -i 's/MaxValue=3/MaxValue=0/g' /home/postmaster.log
But this only works if MaxValue=3 for anyother value it won't work.

use a regexp to catch MaxValue= followed by any number...
s/MaxValue=[0-9]+/MaxValue=0/g
should work.

It sounds like you want
sed -i 's/^MaxValue=.*/MaxValue=0/' /home/postmaster.log
which will find all lines that begin with MaxValue=, and replace each of those lines with MaxValue=0.

You can restrict the lines sed works on as well:
sed -i '/^MaxValue=/s/=[[:digit:]][[:digit:]]*/=0/' /home/postmaster.log

Related

Conditional replace using sed

My question is probably rather simple. I'm trying to replace sequences of strings that are at the beginning of lines in a file. For example, I would like to replace any instance of the pattern "GN" with "N" or "WR" with "R", but only if they are the first 2 characters of that line. For example, if I had a file with the following content:
WRONG
RIGHT
GNOME
I would like to transform this file to give
RONG
RIGHT
NOME
I know i can use the following to replace any instance of the above example;
sed -i 's/GN/N/g' file.txt
sed -i 's/WR/R/g' file.txt
The issue is that I want this to happen only if the above patterns are the first 2 characters in any given line. Possibly an IF statement, although i'm not sure what the condition would look like. Any pointers in the right direction would be much appreciated, thanks.
just add the circumflex, remove g suffix (unnecessary, since you want at most one replacement), you can also combine them in one script.
sed -i 's/^GN/N/;s/^WR/R/' file.txt
Use the start-of-string regexp anchor ^:
sed -i 's/^GN/N/' file.txt
sed -i 's/^WR/R/' file.txt
Since sed is line-oriented, start-of-string == start-of-line.

Replacing strings with special characters with linux sed

I've read lots of posts to understand how to correctly escape white spaces and special characters inside strings using sed, but still i can't make it, here's what i'm trying to achieve.
I have a file containing the some strings like this one:
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.jsessionid=some_value"
and i'm trying to replace 'some_value' using the following:
sed -i "s/^\(JAVA_OPTS=\"\$JAVA_OPTS[ \t]*-Dorg\.apache\.catalina\.jsessionid*=\s*\).*\$/\1$DORG_APACHE_CATALINA_JSESSIONID/" $JBOSS_CONFIGURATION/jboss.configuration
$JBOSS_CONFIGURATION is a variable containing an absolute Linux path.
jboss.configuration is a file i'm pointing as the target for replace
operations.
$DORG_APACHE_CATALINA_JSESSIONID contains the value i want instead
of 'some_value'.
Please note that the pattern:
JAVA_OPTS="$JAVA_OPTS -D
Is always present, and org.apache.catalina.jsessionid is an example of a variable value i'm trying to replace with this script.
What's missing/wrong ? i tried also escaping whitespaces using \s without success,
and echoing the whole gives me the following:
echo "s/^\(JAVA_OPTS=\"\$JAVA_OPTS[ \t]*-Dorg\.apache\.catalina\.jsessionid*=\s*\).*\$/\1$DORG_APACHE_CATALINA_JSESSIONID/"
s/^\(JAVA_OPTS="$JAVA_OPTS[ \t]*-Dorg\.apache\.catalina\.jsessionid*=\s*\).*$/\1/
is echo interpreting the search pattern as sed does ?
any info/help/alternative ways of doing it are highly welcome,
thank you all
echo 'JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.jsessionid=some_value"' | (export DORG_APACHE_CATALINA_JSESSIONID=FOO/BAR/FOOBAR; sed "s/^\(JAVA_OPTS=\"\$JAVA_OPTS[ \t]*-Dorg\.apache\.catalina\.jsessionid*=\s*\).*\$/\1${DORG_APACHE_CATALINA_JSESSIONID////\/}\"/")
Note the bash expansion (in order to escape any / that may trip up sed) and the extra \" after $DORG_APACHE_CATALINA_JSESSIONID in order to properly close the double quote. Other than that your sed expression works for me and the above command outputs the follwoing result:
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.jsessionid=FOO/BAR/FOOBAR"
You can use sed like this:
sed -r '/\$JAVA_OPTS -D/{s/^(.+=).*$/\1'"$DORG_APACHE_CATALINA_JSESSIONID"'/;}' $JBOSS_CONFIGURATION/jboss.configuration
You can specify a pattern that'll match the desired string rather than trying to specify it exactly.
The following should work for you:
sed -i 's#^\(JAVA_OPTS.*Dorg.apache.catalina.jsessionid\)=\([^"]*\)"#\1='"$DORG_APACHE_CATALINA_JSESSIONID"'"#' $JBOSS_CONFIGURATION/jboss.configuration
sed 's/=\w.*$/='"$DORG_APACHE_CATALINA_JSESSIONID"'/' $JBOSS_CONFIGURATION/jboss.configuration

Replace string within a file from a bash script

I need to replace within a little bash script a string inside a file but... I am getting weird results.
Let's say I want to replace:
<tag><![CDATA[text]]></tag>
With:
<tag><![CDATA[replaced_text]]></tag>
Should I use sed? I think due to / and [ ] I am getting weird results...
What would be the best way of approaching this?
Perl with -p option works almost as sed and it has \Q (quote) switch for its regexes:
perl -pe 's{\Q<tag><![CDATA[text]]></tag>}
{<tag><![CDATA[replaced_text]]></tag>}' YOUR_FILE
And in Perl you can use different punctuation to delimiter your expressions (s{...}{...} in my example).
Yes, you need to escape the brackets, and either escape slashes or use different delimiters.
sed 's,<tag><!\[CDATA\[text\]\]></tag>,<tag><!\[CDATA\[replaced)text\]\]></tag>,'
That said, SGML and XML are not actually any better than HTML when it comes to using regexes; don't expect this to generalize.
This should be enough:
$ echo '<tag><![CDATA[text]]></tag>' | sed 's/\[text\]/\[replaced_text\]/'
<tag><![CDATA[replaced_text]]></tag>
You can also change your / separator inside sed to a different character like ,, | or %.
Just use a delimiter other than /, here I use #:
sed -i 's#<tag><!\[CDATA\[text\]\]></tag>#<tag><![CDATA[replaced_text]]></tag>#g' filename
-i to have sed change the file instead of printing it out.
g is for matching more than once (global).
But do you know the exact string you want to match, both the tag and the text?
For instance, if you want to replace the text in all with your replaced_text:
perl -i -pe 's#(<tag><!\[CDATA\[)(.*?)(\]\]></tag>)#\1replaced_text\3#g' filename
Switched to perl because sed doesn't support non-greedy multipliers (the *?).

sed to remove a user in svn access control list

Filename: stackgroup.acl
[groups]
stackoverflow=linus,steve,bill,adrian
stackexchange=charlie,darwin,carol,kelly
I need an sed code that could remove a user whether it's in the start of the line, or the end of it.
Here's what I got so far:
sed 's/\(.*=*\)linus,\(.*\)/\1\2/g'
sed 's/\(.*=*\)steve,\(.*\)/\1\2/g'
sed 's/\(.*=*\),adrian\(.*\)/\1\2/g'
as you can see, the middle one is fine, but the first and last user will leave an additional comma.
I even tried using regex:
sed 's/\(.*=*\),\?linus,\?\(.*\)/\1\2/g'
or
sed 's/\(.*=*\),*linus,*\(.*\)/\1\2/g'
but it's not working.
Can anyone help?
Use two expressions, the 2nd one takes care of the edge case where the name is directly after the =
#!/bin/bash
user="linus"
sed "s/,\?$user//;s/=,/=/" stackgroup.acl
This might work for you:
v1=charlie;v2=darwin;v3=kelly
sed s'/'"$v1"',\?\|,'"$v1"'$//' <<<"stackexchange=charlie,darwin,carol,kelly"
stackexchange=darwin,carol,kelly
sed s'/'"$v2"',\?\|,'"$v2"'$//' <<<"stackexchange=charlie,darwin,carol,kelly"
stackexchange=charlie,carol,kelly
sed s'/'"$v3"',\?\|,'"$v3"'$//' <<<"stackexchange=charlie,darwin,carol,kelly"
stackexchange=charlie,darwin,carol
sed s'/'"$v3"',\?\|,'"$v3"'$//' <<<"stackexchange=kelly"
stackexchange=

sed code to match http://www.domain.com/ and replace with just a / in all files in a directory

I've been searching for this answer for three hours now and I still can't get anything to work. When I run things like this:
sed -i 's/http\:\/\/www\.domain\.org\//\//g checkout_*.php
It drops me into another command line (sorry, I'm very new to sed).
I just want to cd to a dir, grep the dir to see if the string is there then run a replace so I can change my paths from absolute to relative.
You need to close your '. You can also make your command cleaner by using a different sed delimiter to / so that you don't have to escape all those forward slashes in your URL. For example, you can use !, as shown below:
sed -i 's!http://www\.domain\.org/!/!g' checkout_*.php
You just appear to be missing the closing '
sed -i 's/http\:\/\/www\.domain\.org\//\//g' checkout_*.php
Should do what you want ok. But I'd warn you against doing the -i switch without first doing a dry run.

Resources