I've got a property file where I want to do a property substitution, so I wrote a sed patter to change
host = 1234
with another value, but when I execute
echo "host = 1234" | sed 's/\#*\(host[ \t]*\)\=\([ \t]\d*\)/\1\=\1/g'
I got that the substitution is done (host =host) but the \2 atom is also appended to the end of the string (1234). How can I remove it?
`host =host 1234
The first problem is that \d doesn't do what you think. Use [0-9] at least.
You still get host =host out, which seems crazy to me.
EDIT:
Okay
echo "host = 1234" | sed 's/#*\host[ \t]*=[ \t]*\([0-9]*\)/host = asdf/g'
Why capture 'host' if it's always the same? Just rewrite it.
Why preserve the exact tab/space information? Just rewrite it.
Why escape things which are not special?
I hope you get the idea.
But here's what you probably want:
sed '/^#/!s/[ \t]*\([^ \t]*\)[ \t]*=[ \t]*\([^ \t]*\)/\1 = newvalue/g' input_file
This will change anything = anything to anything = newvalue in non-commented lines of input_file. To make it a specific key which is replaced by newvalue, use:
sed '/^#/!s/[ \t]*\(host\)[ \t]*=[ \t]*\([^ \t]*\)/\1 = newvalue/g' input_file
to e.g. replace only lines reading host = anything.
Does this suit your needs?
echo "host = 1234" | cut -d"=" -f 1
yields
host
Then,
echo "host = 1234" | cut -d"=" -f 1
yields
1234
Related
I have lines that start like this: 2141058222 11/22/2017 and I want to append a ; at the end of the ten digit number like this: 2141058222; 11/22/2017.
I've tried sed with sed -i 's/^[0-9]\{10\}\\$/;&/g' which does nothing.
What am I missing?
Try this:
echo "2141058222 11/22/2017" | sed -r 's/^([0-9]{10})/&;/'
echo "2141058222 11/22/2017" | sed 's/ /; /'
Output:
2141058222; 11/22/2017
If the input is always in the format specified, GNU cut works, and might even be more efficient than sed:
cut -c -10,11- --output-delimiter ';' <<< "2141058222 11/22/2017"
Output:
2141058222; 11/22/2017
For an input file that'd be:
cut -c -10,11- --output-delimiter ';' file
I have strings like below
_c_VehCfg1_oCAN00_f276589c_In_Int_buf *pVehCfg1_oCAN00_f276589c_In_IntBuf = (_c_VehCfg1_oCAN00_f276589c_In_Int_buf *)can_Msg_tmp_buffer;
I want replace can_Msg_tmp_buffer with ptr as below
_c_VehCfg1_oCAN00_f276589c_In_Int_buf *pVehCfg1_oCAN00_f276589c_In_IntBuf = (_c_VehCfg1_oCAN00_f276589c_In_Int_buf *)ptr;
I have tried sed as below
echo "_c_VehCfg1_oCAN00_f276589c_In_Int_buf *pVehCfg1_oCAN00_f276589c_In_IntBuf = (_c_VehCfg1_oCAN00_f276589c_In_Int_buf *)can_Msg_tmp_buffer;" | sed 's/\(_C_[[:alnum:]_]*IntBuf = [[:alnum:]_]*\)can_Msg_tmp_buffer/1\ptr/g'
Still I'm not getting expected result instead sed output is same as input.
The problem is I have strings like below also
_c_GW_C4_oCAN00_f276589c_In_Moto_buf *pGW_C4_oCAN00_f276589c_In_MotoBuf = (_c_GW_C4_oCAN00_f276589c_In_Moto_buf *)can_Msg_tmp_buffer;
I only want to replace where type is ending with _Int_buf not _Moto_buf.
It gets extremely convoluted to match individual words with a regex and get a captured group out of it. One way would be to work with known parts of the string which are guaranteed to occur.
For your case, using the strings _In_IntBuf and can_Msg_tmp_buffer; we try to uniquely identify those pattern of lines and do the substitution
sed 's/\(.*\)_In_IntBuf = \(.*\)can_Msg_tmp_buffer;/\1_In_IntBuf = \2ptr;/'
In case you are ok with awk try following.
awk '/_In_IntBuf =/{sub(/can_Msg_tmp_buffer/,"ptr")} 1' Input_file
In case you want to save output into Input_file itself append > temp_file && mv temp_file Input_file in above code.
I have a large php script that contains the following line
$user = $_REQUEST['user'];
The exact match only appears once in the entire page. I want to change it to
$user = urldecode($_REQUEST['user']);
Can someone advise the best way ?
I'm thinking SED, but everything I've tried has failed to find and replace it.
Any ideas ?
Thanks
Following should help you in same.
sed 's/^$user = $_REQUEST\['"'"'user'"'"'\]\;$/$user = urldecode($_REQUEST\['"'"'user'"'"'\]);/' Input_file
Let's say following is the Input_file(I am assuming here).
cat Input_file
^#^#^#^#00000305^#^#^#^#^#^#430^#430^#^#^#^#^#^#^#^#^#09079989530
$user = $_REQUEST['user'];
tefqfwqfb$user = $_REQUEST['user'];
wvwrjvnwvjn$user = $_REQUEST['user'];fwvwrev
So after running above code following will be the output.
sed 's/^$user = $_REQUEST\['"'"'user'"'"'\]\;$/$user = urldecode($_REQUEST\['"'"'user'"'"'\]);/' Input_file
^#^#^#^#00000305^#^#^#^#^#^#430^#430^#^#^#^#^#^#^#^#^#09079989530
$user = urldecode($_REQUEST['user']);
tefqfwqfb$user = $_REQUEST['user'];
wvwrjvnwvjn$user = $_REQUEST['user'];fwvwrev
sed approach:
sed -E "s/^(\\\$user = )(\\\$_REQUEST\['user'\])/\1urldecode(\2)/" file.php
$ awk 'index($0,"$user = $_REQUEST[\047user\047];") { sub(/= /,"&urldecode("); sub(/;/,")&") } 1' file
$user = urldecode($_REQUEST['user']);
This might work for you (GNU sed):
sed '/^$user = $_REQUEST\['\''user'\''\];$/s/$_[^;]*/urldecode(&)/' file
Match the string and then use substitution to amend part of it.
N.B. '\'' closes the current single quoted sed command, introduces another single quote and then begins the rest of the sed command i.e. it punches a hole through to the shell and then quotes a single quote.
How to print only string figure with the following line :
\begin{figure}[h!]
I tried :
firstLine='\begin{figure}[h!]'
echo $firstLine | sed -n 's/\\begin{\(.*\)}/\1/p'
but returns :
figure[h!] instead of figure
It seems that issue comes from [] or ! character.
firstLine='\begin{figure}[h!]'
echo "$firstLine" | sed 's/.*{\(.*\)}.*/\1/'
Output:
figure
With your code (add .*):
echo $firstLine | sed -n 's/\\begin{\(.*\)}.*/\1/p'
This might work for you (GNU sed):
sed 's/.*{\(.*\)}.*/\1/' file
This assumes there is only one {...} expression and one line.
A more rigorous solution would be:
sed -n 's/.*\\begin{\([^}]*\)}.*/\1/p' file
However nothing would be output if no match was found.
I want to read from the file /etc/lvm/lvm.conf and check for the below pattern that could span across multiple lines.
tags {
hosttags = 1
}
There could be as many white spaces between tags and {, { and hosttags and so forth. Also { could follow tags on the next line instead of being on the same line with it.
I'm planning to use awk and sed to do this.
While reading the file lvm.conf, it should skip empty lines and comments.
That I'm doing using.
data=$(awk < cat `cat /etc/lvm/lvm.conf`
/^#/ { next }
/^[[:space:]]*#/ { next }
/^[[:space:]]*$/ { next }
.
.
How can I use sed to find the pattern I described above?
Are you looking for something like this
sed -n '/{/,/}/p' input
i.e. print lines between tokens (inclusive)?
To delete lines containing # and empty lines or lines containing only whitespace, use
sed -n '/{/,/}/p' input | sed '/#/d' | sed '/^[ ]*$/d'
space and a tab--^
update
If empty lines are just empty lines (no ws), the above can be shortened to
sed -e '/#/d' -e '/^$/d' input
update2
To check if the pattern tags {... is present in file, use
$ tr -d '\n' < input | grep -o 'tags\s*{[^}]*}'
tags { hosttags = 1# this is a comment}
The tr part above removes all newlines, i.e. makes everything into one single line (will work great if the file isn't to large) and then search for the tags pattern and outputs all matches.
The return code from grep will be 0 is pattern was found, 1 if not.
Return code is stored in variable $?. Or pipe the above to wc -l to get the number of matches found.
update3
regex for searcing for tags { hosttags=1 } with any number of ws anywhere
'tags\s*{\s*hosttags\s*=\s*1*[^}]*}'
try this line:
awk '/^\s*#|^\s*$/{next}1' /etc/lvm/lvm.conf
One could try preprocessing the file first, removing commments and empty lines and introducing empty lines behind the closing curly brace for easy processing with the second awk.
awk 'NF && $1!~/^#/{print; if(/}/) print x}' file | awk '/pattern/' RS=