How to use Sed command to get following output? - sed

My input is:
"INTC_KEY,ABC1|OBJID,ABC2"
And I want to send the output to a file like:
DDS.INTC_KEY = REPL.OBJID AND DDS.ABC1 = REPL.ABC2
Here is what I've tried so far:
sed 's/^/DDS./g' | sed 's/|/=REPL./g' | tr '\n' '~' | sed 's/~/_N~/g' | sed 's/~$/\n/g' | sed 's/~/~\n/g' | sed 's/~/ AND/g' > ${LOG_DIR}/JOIN.tmp

Based on the single line of input, the following regular expression will transform the input into the desired output:
s/"\([^,]*\),\([^|]*\)|\([^,]*\),\(.*\)"/DDS.\1 = REPL.\3 AND DDS.\2 = REPL.\4/
This shell command shows it working:
$ echo '"INTC_KEY,ABC1|OBJID,ABC2"' | sed 's/"\([^,]*\),\([^|]*\)|\([^,]*\),\(.*\)"/DDS.\1 = REPL.\3 AND DDS.\2 = REPL.\4/'
DDS.INTC_KEY = REPL.OBJID AND DDS.ABC1 = REPL.ABC2
The regular expression basically matches four pieces of text (using the escaped parentheses), delimited by the commas and vertical bar and made available as the \1-\4 back references for the substitution.
Note: I’ve tried to stick to using the features of standard sed and I tested using GNU sed with the POSIXLY_CORRECT environment variable set to 1 to emulate standard sed.

Related

How to extract a specific character inside a parentheses using sed command?

I want to extract an atomic symbols inside a parentheses using sed.
The data I have is in the form C(X12), and I only want the X symbol
EX: that a test command :
echo "C(Br12)" | sed 's/[0-9][0-9])$//g'
gives me C(Br.
You can use
sed -n 's/.*(\(.*\)[0-9]\{2\})$/\1/p'
See the online demo:
sed -n 's/.*(\(.*\)[0-9]\{2\})$/\1/p' <<< "c(Br12)"
# => Br
Details
-n - suppresses the default line output
.*(\(.*\)[0-9]\{2\})$ - a regex that matches
.* - any text
( - a ( char
\(.*\) - Capturing group 1: any text up to the last....
[0-9]\{2\} - two digits
)$ - a ) at the end of string
\1 - replaces with Group 1 value
p - prints the result of the substitution.
For example:
echo "C(Br12)" | sed 's/C(\(.\).*/\1/'
C( - match exactly literally C(
. match anything
\(.\) - match anythig - one character- and "remember" it in a backreference \1
.* ignore everything behind it
\1 - replace it by the stuff that was remembered. The first character.
Research sed, regex and backreferences for more information.
Try using the following command
echo "C(BR12)" | cut -d "(" -f2 | cut -d ")" -f1 | sed 's/[0-9]*//g'
The cut tool will split and get you the string in middle of the paranthesis.Then pass the string to a sed for replacing the numbers inside the string.
Not a fully sed solution but this will get you the output.

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.

Why does sed only replace the first character?

$ echo lcdefghijklmnopqrstblvcxyz | tr [a-i] [1-9] | sed 's/j/10/' | sed 's/k/11/' | sed 's/l/12/' | sed 's/m/13/' | sed 's/n/14/' | sed 's/o/15/' | sed 's/p/16/' | sed 's/q/17/' | sed 's/r/18/' | sed 's/s/19/' | sed 's/t/20/' | sed 's/u/21/' | sed 's/v/22/' | sed 's/w/23/' | sed 's/x/24/' | sed 's/y/25/' | sed 's/z/26/'
1234567891011l13141516171819202l223242526
The long command is intended to replace a..z with 1..26. Notice there are 3 "l" characters in the echoed string. Why is the first one correctly converted to "12" yet the other two (results 11l13 and 202l223) aren't?
I tried this on both my Windows 7 PC running Cygwin (bash 4.3.33(1)-release (x86_64-unknown-cygwin)) and on my MacBook Pro running Terminal (bash 3.2) and got the same results. I expected the result to be 1..26 concatenated. This is part of a bigger problem that I reduced to this test case.
You need the g flag for the substitution to be repeated:
$ echo lll | sed 's/l/12/'
12ll
$ echo lll | sed 's/l/12/'g
121212
Without the g flag, s replaces the first instance, as documented in man sed.
Also, you can put all of those commands in a single invocation of sed. You don't need all those pipes:
sed 's/j/10/g;s/k/11/g;s/l/12/g...'
Multiple sed commands (with g switch)
Under bash, you could try something like:
c=1 o=
for i in {a..z};do
o+="s/$i/$((c++))/g;"
done
sed -e "$o" <<<'lcdefghijklmnopqrstblvcxyz'
1234567891011121314151617181920212223242526
or
fold -s <<< ${o//;/; }
s/a/1/g; s/b/2/g; s/c/3/g; s/d/4/g; s/e/5/g; s/f/6/g; s/g/7/g; s/h/8/g;
s/i/9/g; s/j/10/g; s/k/11/g; s/l/12/g; s/m/13/g; s/n/14/g; s/o/15/g; s/p/16/g;
s/q/17/g; s/r/18/g; s/s/19/g; s/t/20/g; s/u/21/g; s/v/22/g; s/w/23/g; s/x/24/g;
s/y/25/g; s/z/26/g;
then
sed -e '
s/a/1/g; s/b/2/g; s/c/3/g; s/d/4/g; s/e/5/g; s/f/6/g; s/g/7/g; s/h/8/g;
s/i/9/g; s/j/10/g; s/k/11/g; s/l/12/g; s/m/13/g; s/n/14/g; s/o/15/g; s/p/16/g;
s/q/17/g; s/r/18/g; s/s/19/g; s/t/20/g; s/u/21/g; s/v/22/g; s/w/23/g; s/x/24/g;
s/y/25/g; s/z/26/g;
' <<<'lcdefghijklmnopqrstblvcxyz'
1234567891011121314151617181920212223242526
This might work for you (GNU sed):
sed -r '1{x;s/^/a1b2c3d4e5f6g7h8i9j10k11l12m13n14o15p16q17r18s19t20u21v22w23x24y25z26/;x};G;:a;s/([a-z])(.*\n.*\1([0-9]+))/\3\2/;ta;P;d' file
This uses a lookup table to translate the required strings.

replace a line that contains a string with special characters

i want to replace lines which contains a string that has some special characters.
i used \ and \ for escape special characters but nothing changes in file.
i use sed like this:
> sed -i '/pnconfig\[\'dbhost\'\] = \'localhost\'/c\This line is removed.' tco.php
i just want to find lines that contains :
$pnconfig['dbhost'] = 'localhost';
and replace that line with:
$pnconfig['dbhost'] = '1.1.1.1';
Wrap the sed in double quotes as
sed -i "s/\(pnconfig\['dbhost'\] = \)'localhost'/\1'1.1.1.1'/" filename
Test
$ echo "\$pnconfig['dbhost'] = 'localhost';" | sed "s/\(pnconfig\['dbhost'\] = \)'localhost'/\1'1.1.1.1'/"
$pnconfig['dbhost'] = '1.1.1.1';
Use as below:
sed -i.bak '/pnconfig\[\'dbhost\'\] = \'localhost\'/pnconfig\[\'dbhost\'\] = \'1.1.1.1\'/' tco.php
Rather than modifying the file for the first time, create back up and then search for your pattern and then replace it with the other as above in your file tco.php
You don't have to worry about backslashing single quotes by using double quotes for sed.
sed -i.bak "/pnconfig\['dbhost'\] = 'localhost'/s/localhost/1.1.1.1/g" File
Try this one.
sed "/$pnconfig\['dbhost']/s/localhost/1.1.1.1/"

How do I search for a keyword in a file and print out the string following the keyword?

I want to search for keyword "mykey = " in a file and print out the string that is following the keyword.
I cannot do a "grep", because each line is very long. I just want to extract the string following the keyword.
Here's what I came up with. Not first, but works, and without the final grep.
grep 'mykey = ' file | sed 's/.*\(mykey = [A-Za-z]*\).*/\1/'
Assuming the keyword is a single word and a space follows it, like this:
mykey = myCoolValue
grep 'mykey' /your/file/here | sed -r 's/.*mykey = (^[ ]*) .*/\1/g' | grep .
If you have pcregrep at hand, you can issue this command in terminal or in a script to get only desired text after mykey =
$ pcregrep -o '(?<=mykey = ).+' file
The regex uses a positive lookbehind, where -o returns only the matched text, not the whole line.