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.
Related
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]+'
This question already has answers here:
How to escape single quote in sed?
(9 answers)
Closed 3 years ago.
I wish to use sed in ubuntu to replace a row in a file file.txt.
my row starts with a certain pattern foo followed by any number of any characters. I wish to replace this with foo='x'. I was trying to use the following command from bash:
sed -i 's/^foo*/foo='x'/g' file.txt
Obviously the ' symbol brakes the string transferred to sed. Moreover, the regular expressions don't sim to work for me when I remove the problematic symbol. I simply replace only the pattern foo and not the whole row.
For example the original file.txt:
foo='bla'
The requested result file.txt:
foo='SomethingElse'
I tried a number of variables such as: sed -i 's/\^foo\*/foo=\'x\'/g' file.txt to no avail. I could not find information on the subject online though I am sure this is not the first time someone encountered this problem.
How do I use ' in the target (or the pattern I am searching for that matter)?
And what is up with the regex in this approach?
Using sed
sed "/foo/s/='.*'/='1234'/g" file
foo='1234'
This search for foo, then replace =' with ='1234 on that line.
When you have ' int your text, change start and stop of sed to "
Another variation using back reference and -E
sed -E "s/(foo=').*/\11234'/g" file
foo='1234'
If you like to use single quote, you have to get out of sed with single quote and then escape the single quote and then a new single quote to get in to sed like this messy solution:
sed '/foo/s/='\''.*/='\''1234'\''/g' file
or hex code it:
sed '/foo/s/=\x27.*\x27/=\x271234\x27/g' file
This question already has answers here:
Difference between single and double quotes in Bash
(7 answers)
Closed 8 years ago.
I am trying to comment the lines in my scripts where a pattern from a given list of patterns is present. Now, I am able to do it the following way on command line :
sed '/abcdefg/ s/^/#/' file.sql > file.commented
But if I use a variable for pattern (instead of abcdefg directly as above) I'm not able to do the same.
pattern=abcdefg
sed '/$pattern/ s/^/#/' file.sql > file.commented
Looks like it is escaping the dollar character and not taking the value of the variable.
How do you do the same with awk?
You need to use double quote to make it work with variables in shell:
sed "/$pattern/ s/^/#/" file.sql > file.commented
You can also use inline feature of shell to save changes in input file itself
sed -i.bak "/$pattern/ s/^/#/" file.sql
However it is best to avoid sed for this job since it uses regex and above command will break if $pattern contains / or some special regex meta character. Better to use awk like this:
awk -v p="$pattern" 'index($0, p) {$0 = "#" $0} 1' file.sql > file.commented
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.
This question already has answers here:
Using Sed to expand environment variables inside files
(2 answers)
Closed 8 years ago.
I have a file name temp.txt with content as
ANSWER "1234:IDGK"
ANSWER "123456:DEF"
I need to change answer "1234:$1"with input parameter from script.
Right now, I am using the code below in script (run.sh) to change the content in temp.txt
#!/bin/bash
Prompt1=$1
sed -i -e "s/\(1234:\).*/\1$1/" temp.txt
But when I run the script with any input value {irrespective of length of value} " is over written in temp.txt.
for example
./run.sh ABCDEF
temp.txt is updated as
ANSWER "1234:ABCDEF
ANSWER "123456:DEF"
The expected output is
ANSWER "1234:ABCDEF"
ANSWER "123456:DEF"
Note: input value in file will always not be same so I can't go with
sed s/IDGK/ABCDEF/g
Please suggest correct SED command which will replace the only text and not the ".
Since you don't want the trailing double quote deleted, you need to exclude it from the substitution. For example:
sed -i -e "s/\(1234:\).*\(.\)/\1$1\2/" temp.txt
The second capture matches the last character on the line, the double quote.
Or:
sed -i -e 's/\(1234:\)[^"]*'"/\1$1/" temp.txt
Instead of matching any character, only match characters that are not double quotes. Note the use of single quotes and double quotes to ensure the double quote in the negated character class is a double quote. Alternatively again:
sed -i -e "s/\(1234:\)[^\"]*/\1$1/" temp.txt
This escapes the double quote with a backslash. It isn't the way I'd do it, but it will work fine.
You can try this.
sed -i -e 's/\(1234:\).*/\1'$1'"/' temp.txt
Last character will be the double quotes. So you can directly place that in the substitution. Or else you can try this.
sed -i -e 's/\(1234:\)[^"]*/\1'$1'/' temp.txt
If your system not allow to use the -i option, you can use the redirect like this.
sed -e 's/\(1234:\)[^"]*/\1'$1'/' temp.txt > temp.txt