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.
Related
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.
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
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:
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
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.