Use Variable in SED [duplicate] - regex

This question already has answers here:
Escape a string for a sed replace pattern
(17 answers)
Closed 4 years ago.
I cannot expand this variable in sed. I've tried everything I can think of.
I am trying to put the md5sum of file1 in line 10 of file2
I can take $x out of the regex and put some text and it works. It just will not accept the variable. printf the variable is fine.
#!/bin/bash
x=$(md5sum /etc/file1)
printf "$x \n"
sed -i 10"s/.*/$x/g" /usr/bin/file2

You may use this command that uses ~ as regex delimiter instead of / since output of md5sum contains /:
sed -i "10s~.*~$x~" /usr/bin/file2

After I reduced the variable from the md5sum output which includes the filename and directory by running $x thru:
x=$(echo $x | head -n1 | awk '{print $1;}')
Leaving only the MD5 it worked and quit erroring.

Related

Extract word and digit from string using SED [duplicate]

This question already has answers here:
sed: print only matching group
(5 answers)
Closed 2 years ago.
how can I extract the TIC-9890 from a
branch name that looks like feature/TIC-9890/some-other-wording
I am not a SED expert, but I managed to come up with:
echo "feature/TIC-000/random-description" |
sed -n 's/.*\(TIC-[0-9]\{1,\}\).*/\1/'
This seems to work fine if the TIC-\d+ string is in there,
but returns the entire string if that is missing...
However, I need it to return null or empty string if the match isn't present.
You should add a p option to print and it should fly then. Why because we have stopped printing of sed by using -n option so when substitution happens then p needs to be used to print it.
echo "feature/TIC-000/random-description" | sed -n 's/.*\(TIC-[0-9]\{1,\}\).*/\1/p'
From man sed page:
-n, --quiet, --silent suppress automatic printing of pattern space
p Print the current pattern space.
OR as per #anubhava sir's comments one could use grep with -E option we could try:
echo "feature/TIC-000/random-description" | grep -oE 'TIC-[0-9]+'

Dynamically substitue pattern with env variable with bash [duplicate]

This question already has answers here:
Bash Search File for Pattern, Replace Pattern With Code that Includes Git Branch Name
(1 answer)
Replace a string in shell script using a variable
(12 answers)
Closed 6 years ago.
I have a file file.txt with this content: Hi {YOU}, it's {ME}
I would like to dynamically create a new file file1.txt like this
YOU=John
ME=Leonardo
cat ./file.txt | sed 'SED_COMMAND_HERE' > file1.txt
which content would be: Hi John, it's Leonardo
The sed command I tried so far is like this s#{\([A-Z]*\)}#'"$\1"'#g but the "substitution" part doesn't work correctly, it prints out Hi $YOU, it's $ME
The sed utility can do multiple things to each input line:
$ sed -e "s/{YOU}/$YOU/" -e "s/{ME}/$ME/" inputfile.txt >outputfile.txt
This assumes that {YOU} and {ME} occurs only once each on the line, otherwise, just add g ("s/{YOU}/$YOU/g" etc.)
You can use awk with 2 files.
$> cat file.txt
Hi {YOU}, it's {ME}
$> cat repl.txt
YOU=John
ME=Leonardo
$> awk -F= 'FNR==NR{a["{" $1 "}"]=$2; next} {for (i in a) gsub(i,a[i])}1' repl.txt file.txt
Hi John, it's Leonardo
First awk command goes through replacement file and stores each key-value in an array a be wrapping keys with { and }.
In second iteration we just replace each key by value in actual file.
Update:
To do this without creating repl.txt you can use `process substitution**:
awk -F= 'FNR==NR{a["{" $1 "}"]=$2; next} {
for (i in a) gsub(i,a[i])} 1' <(( set -o posix ; set ) | grep -E '^(YOU|ME)=') file.txt

sed command not updating text file [duplicate]

This question already has answers here:
How to use variables in a command in sed?
(4 answers)
Closed 8 years ago.
Would like to ask because I'm having an issue with sed command in unix scripting.
#!/bin/sh
cnt=2
sed '1 c\
$cnt' test.txt
I want to replace the first line of text file test.txt with the value of variable cnt which is 2. How can I pass the variable on the above sed command? The sed command treats $cnt as string.
Variables are not expanded in single quotes. They are expanded in double quotes, though.
sed "1 c\\
$cnt" test.txt
Note that sed doesn't update the input file by default, it outputs the changed version instead. If your implementation of sed supports it, use the -i switch to modify the input file. Otherwise, you'd have to redirect the output to a new file and rename it back to the original name:
sed "..." text.txt > text.new
mv text.new text.txt
Change to:
#!/bin/sh
cnt=2
sed "1 c\
$cnt" test.txt
For variable interpolation to happen, u need to put it within double quotes rather than single quotes.

Sed command does not replace string with special characters [duplicate]

This question already has answers here:
sed search and replace strings containing / [duplicate]
(2 answers)
Closed 8 years ago.
I have a script which is getting value from a ".properties" file. It replaces the value successfully if it is a simple string but if contains escape characters like ('\') it does not work. Can anybody point out please that what to do, i have searched on the internet but unable to understand the "REGEX".
Script File:
#!/bin/bash
# Omer's First Script
#Include Properties File
. directoryPaths.properties
echo "Start"
sed -i "s/DONEDIRECTORY/$DoneDirectory/" *TestFile*
echo "finish"
directoryPaths.properties
DoneDirectory=/home/omerkhalid/Documents/Test/Done
TestFile.txt
This is a test Document.
DONEDIRECTORY
Error:
sed: -e expression #1, char 18: unknown option to `s'
Note:
If i change the value of "DoneDirectory" to simple string i.e. "Done" , it works fine. But with "/" escape characters it doesn't work.
Problem is not with the sed command but with the contents of the variable $DoneDirectory.
In the sed command
sed -i "s/DONEDIRECTORY/$DoneDirectory/" *TestFile*
/ is used as the delimitter, there by sed expects only 3 slashes following the s command. But once the variable $DoneDirectory is substituted there are 8 / which gives the error
Solution
Use some other delimeters in sed like
sed -i "s#DONEDIRECTORY#$DoneDirectory#" *TestFile*
Since the variable $DoneDirectory contains sed's default command delimiter / I would use a different delimiter:
sed -i "s#DONEDIRECTORY#$DoneDirectory#" *TestFile*
I would argue that sed is not the right tool for this job. Sure, you can work with other delimiters, but if the other delimiter shows up in your string (or a backslash, or something else that sed interprets), it's still going to explode. I believe awk is better suited:
awk -v subst="$DoneDirectory" '{ sub("DONEDIRECTORY", subst); print $0 }' TestFile
Note: use gsub instead of sub if DONEDIRECTORY can show up more than once in a line and both should then be substituted.

using vars as numbers in sed [duplicate]

This question already has answers here:
sed substitution with Bash variables
(6 answers)
Closed 8 years ago.
Having some difficulty in getting a sed | grep pipe to work when using vars as numbers.
In the string below the '3,5p' works fine, but when substituting the numbers for vars I get the error
sed: -e expression #1, char 4: extra characters after command
working=$(sed -n '3,5p' ${myFile} | grep -n "string" |cut -f1 -d: )
notWorking=$(sed -n '${LINESTART},${LINEEND}p' ${myFile} | grep -n "string" |cut -f1 -d: )
I would also be interested in any advice how I could change command so the line number returned is replaced with $string2 in the file myFile
thanks
Art
You need the variables to be expanded by sed. For that, you have to enclose the expression within double quotes:
sed -n "${LINESTART},${LINEEND}p" ${myFile}
^ ^
instead of
sed -n '${LINESTART},${LINEEND}p' ${myFile}
As you are checking for the line number in $myFile where string is found, it line is in between $LINESTART and $LINEEND, you can do:
awk 'NR>=start && NR<=end && /string/ {print NR}' start=$LINESTART end=$LINEEND ${myFile}
Suppose you want to replace a string just if it appears in specific lines. You can use this:
sed -i.bak "$LINESTART,$LINEEND s/FIND/REPLACE/' file
-i.bak makes a backup of the file and does an in-place edit: file will contain the modified file, while file.bak will be the backup.
Test
$ cat a
hello
this is
something
i want changed
end
but this is not to be changed
$ sed -i.bak '3,5 s/changed/NEW/' a
$ cat a
hello
this is
something
i want NEW <---- "changed" got replaced
end
but this is not to be changed <---- this "changed" did not