SED using variables that includes new lines - sed

I have these two vars (the empty space is to be included and have new line):
oldValue:
related_pg_pin : vph;
value : 8;
newValue:
related_pg_pin : vph;
value : 11500;
And I want to substitute the oldValue with newValue. I'm using this command:
sed -i "s/${oldValue}/${newValue}/g" $file
But I'm getting this error:
/bin/sed: -e expression #1, char 27: unterminated `s' command
Any idea what is the source of the problem? I've tried several things but none works.

This sed may work for you.
$ sed -zi "s/\n//;s/$(sed -z 's/\n//' <<< $oldValue)/$(sed -z 's/\n//' <<< $newValue)/;s/;/&\n/" input_file
related_pg_pin : vph;
value : 11500;

I found an alternative solution in my script. In the end I used a simple sed command. Thank you everyone!

Related

Syntax error using sed for a find and replace

I am trying to do a find and replace using sed. I am trying to find that : purge: [], to replace by purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"], but it does not work, here is my commande :
sed -i -e 's/purge: [],/purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"],/g' myfile.txt
Could you help me please ?
Thank you very much !
You need to:
Change delimiters to a char other than a /, like ~ or !, or escape / delimiter chars inside the pattern (I'd suggest the former)
Escape the [ char in the pattern.
You can use
sed -i 's!purge: \[],!purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"],!g' myfile.txt
See the online demo:
#!/bin/bash
s='Blah..purge: [], blah...'
sed 's!purge: \[],!purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"],!g'<<< "$s"
# => Blah..purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"], blah...

How to replace a block of code between two patterns with blank lines?

I am trying replace a block of code between two patterns with blank lines
Tried using below command
sed '/PATTERN-1/,/PATTERN-2/d' input.pl
But it only removes the lines between the patterns
PATTERN-1 : "=head"
PATTERN-2 : "=cut"
input.pl contains below text
=head
hello
hello world
world
morning
gud
=cut
Required output :
=head
=cut
Can anyone help me on this?
$ awk '/=cut/{f=0} {print (f ? "" : $0)} /=head/{f=1}' file
=head
=cut
To modify the given sed command, try
$ sed '/=head/,/=cut/{//! s/.*//}' ip.txt
=head
=cut
//! to match other than start/end ranges, might depend on sed implementation whether it dynamically matches both the ranges or statically only one of them. Works on GNU sed
s/.*// to clear these lines
awk '/=cut/{found=0}found{print "";next}/=head/{found=1}1' infile
# OR
# ^ to take care of line starts with regexp
awk '/^=cut/{found=0}found{print "";next}/^=head/{found=1}1' infile
Explanation:
awk '/=cut/{ # if line contains regexp
found=0 # set variable found = 0
}
found{ # if variable found is nonzero value
print ""; # print ""
next # go to next line
}
/=head/{ # if line contains regexp
found=1 # set variable found = 1
}1 # 1 at the end does default operation
# print current line/row/record
' infile
Test Results:
$ cat infile
=head
hello
hello world
world
morning
gud
=cut
$ awk '/=cut/{found=0}found{print "";next}/=head/{found=1}1' infile
=head
=cut
This might work for you (GNU sed):
sed '/=head/,/=cut/{//!z}' file
Zap the lines between =head and =cut.

Sed substitute: make a group operator optional

Let's say I want to use sed to substitute expressions like "foo", "foo(1 1)", "foo(42 1)" by "bar". I tried :
sed -i ':a;N;$!ba;s/foo([0-9]\+ [0-9]\+)\{0,1\}/bar/g' input.file
But only replaced expressions with parenthesis after foo, not foo with no parenthesis.
Do you have any idea why ?
Example of I wish:
INPUT
foo
foo(236 124)
OUPUT
bar
bar
You can use this sed:
sed 's/foo\(([0-9]\+ [0-9]\+)\)\{0,1\}/bar/g' file
^ ^
Here, I have added grouping. So that, {0,1} would work exactly.
Test:
$ sed 's/foo\(([0-9]\+ [0-9]\+)\)\{0,1\}/bar/g' file
bar
bar
With GNU sed:
sed -E 's/foo(\([0-9]+ [0-9]+\))?/bar/' file

Print pattern on a string with special character

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.

How to replace # using sed c0mmand?

I have the following header :
#SRR1561197.1/1
#SRR1561197.2/1
#SRR1561197.3/1
#SRR1561197.4/1
I want to Add few letters after # and before SRR like this:
#MexD1SRR1561197.1/1
#MexD1SRR1561197.2/1
#MexD1SRR1561197.3/1
#MexD1SRR1561197.4/1
I tried:
sed 's/#/#MexD1/File,fastq > change.fastq
This results in empty file..
Use sed with the in file replacement option. The g at the end makes it global.
sed -i 's/#/#MexD1/g' file
To fix your code.
sed 's/#/#MexD1/g' File.fastq > change.fastq
You have to escape it: sed s/\#/\#MexD1/g source-file-name > change.fastq