Sed unterminated 's command in script - sed

inside minor1.sed
sed -r 's/8/1/g' phone.txt
inside phone.txt
(866) 879-7647
(888) 474-7424
(371) 670-6006
(866) 266-5588
(844) 415-3955
(800) 237-2747
command issued
sed -r -f minor1.sed phone.txt
no matter what I do im given the unterminated 's command error.

minor1.sed should contain only sed expression, s/8/1/g in your case:
val#chi:~$ cat minor1.sed
s/8/1/g
val#chi:~$ sed -r -f minor1.sed phone.txt
(166) 179-7647
(111) 474-7424
(371) 670-6006
(166) 266-5511
(144) 415-3955
(100) 237-2747

Related

Replace value in single quotes using sed

I already know that sed uses own approach to deal with single quote but I think it still possible to use it in my automation script.
I had to replace value of fingerprint in Saltstack config file.
Current value:
#master_finger: ''
Target value
master_finger: 'some:value'
My current command which doesn't work:
$ sed -i 's/#master_finger: ''/master_finger: 'some:value'/g' /etc/salt/minion
returns:
master_finger: some:value''
How can I solve this?
just use the double quotes to enclose the script.
$ echo "#master_finger: ''" | sed "s/#master_finger: ''/master_finger: 'some:value'/"
master_finger: 'some:value'
It's not sed that's making handling of 's difficult, it's the shell because the shell does not allow 's within any '-quoted string, including scripts.
You could save the sed script in a file and run it with -f or use a here document:
$ sed -f- file <<'EOF'
s/#master_finger: ''/master_finger: 'some:value'/g
EOF
master_finger: 'some:value'
To see the difference between the above and #karakfas suggestion:
$ sed -f- file <<'EOF'
s/#master_finger: ''/master_finger: '$(date)'/g
EOF
master_finger: '$(date)'
$ sed "s/#master_finger: ''/master_finger: '$(date)'/" file
master_finger: 'Sun Feb 14 06:50:43 CST 2021'
and imagine if date was replace by rm -rf * or something worse.
Also consider:
$ sed 's/#master_finger: '\'\''/master_finger: '\''$(date)'\''/' file
master_finger: '$(date)'

How do I add the sed command inside a bash script?

I want to add below line to build.sh file to a line number 26
sed -i 's/-DskipTests //' dev/make-distribution.sh
I tried with this command
sed "26 a sed -i 's/-DskipTests //' dev/make-distribution.sh" build.sh
But this is giving error
sed: 1: "26 a sed -i 's/-DskipTe ...": command a expects \ followed by text`
Try putting it in as if it were multiline add as a workaround. Does this work for you?
sed "26 a\\sed -i 's/-DskipTests //' dev/make-distribution.sh" build.sh
You need to quote your quote since you are compounding quote-types.
c.f. the manual, though - it ought to work as it is.

SH - Replace text

I want to replace one string with another but I can't. The code is:
updatedb
MCRYPTINI=$(locate mcrypt.ini | grep 'apache2')
MCRYPTSO=$(locate mcrypt.so | grep "/mcrypt.so")
OLD="extension=mcrypt.so"
NEW="extension=$MCRYPTSO"
echo $MCRYPTINI
echo $MCRYPTSO
echo $OLD
echo $NEW
echo "'s/$OLD/$NEW' $MCRYPTINI"
sed -i 's/$OLD/$NEW' $MCRYPTINI
And the result is:
sudo sh testScript.sh
/etc/php5/apache2/conf.d/20-mcrypt.ini
/usr/lib/php5/20121212/mcrypt.so
extension=mcrypt.so
extension=/usr/lib/php5/20121212/mcrypt.so
's/extension=mcrypt.so/extension=/usr/lib/php5/20121212/mcrypt.so' /etc/php5/apache2/conf.d/20-mcrypt.ini
sed: -e expression #1, char 11: unterminated `s' command
For the response I don't need to use 'sed', but it's looks easy and good.
I use sh not bash because I want the code can use in all the systems, so I prefer answers that follow that principle
UPDATE
sed -i "s/$OLD/$NEW/" $MCRYPTINI
error:
sed: -e expression #1, char 14: unknown option to `s'
Add a slash and double quotes:
sed -i "s/$OLD/$NEW/" file
The solution could be:
sed -i "s/$OLD/$NEW/" $MCRYPTINI
but $NEW is a path, so I need to change "/" by other character, for example "+"
sed -i "s+$OLD+$NEW+" $MCRYPTINI

Sed remove matching lines script

I'm requesting help with a very simple script...
#!/usr/bin/sed -f
sed '/11,yahoo/d'
sed '/2506,stackover flow/d'
sed '/2536,reddit/d'
Just need it to remove three matches that account for 18408 in my file, data.csv
% sed -f remove.sed < data.csv
sed: 3: remove.sed: unterminated substitute pattern
Doing these same lines individually is no problem at all, so what am I doing wrong with this?
Using freeBSD 10.1 and its implementation of sed, if that matters.
This, being a sed script, should not have "sed" at each line.
Either change it to:
#!/usr/bin/sed -f
/11,yahoo/d
/2506,stackover flow/d
/2536,reddit/d
Or to
#!/bin/sh
sed -e /11,yahoo/d \
-e /2506,stackover flow/d \
-e /2536,reddit/d

sed error - unterminated substitute pattern

I am in directory with files consisting of many lines of lines like this:
98.684807 :(float)
52.244898 :(float)
46.439909 :(float)
and then a line that terminates:
[chuck]: cleaning up...
I am trying to eliminate :(float) from every file (but leave the number) and also remove that cleaning up... line.
I can get:
sed -ie 's/ :(float)//g' *
to work, but that creates files that keeps the old files. Removing the -e flag results in an unterminated substitute pattern error.
Same deal with:
sed -ie 's/[chuck]: cleaning up...//g' *
Thoughts?
sed -i '' -e 's/:(float)//' -e '/^.chuck/d' *
This way you are telling sed not to save a copy (null length backup extention to -i) and separately specifying the sed commands.
sed -ie expression [files...]
is equivalent to:
sed -ie -e expression [files...]
and both mean apply expression to files, overwriting the files, but saving the old files with an "e" as the backup suffix.
I think you want:
sed -i -e expression [files...]
Now if you're getting an error from that there must be something wrong with your expression.
your numbers are separated with (float) by the : character. Therefore, you can use awk/cut to get your numbers. Its simpler than a regex
$ head -n -1 file | awk -F":" '{print $1}'
98.684807
52.244898
46.439909
$ head -n -1 file | cut -d":" -f1
98.684807
52.244898
46.439909
Solution :
sed -i '' 's/ :(float)//g' *
sed -i '' 's/[chuck]: cleaning up...//g' *
Explanation :
I can get:
sed -ie 's/ :(float)//g' *
to work, but that creates files that keeps the old files.
That's because sed's i flag is supposed to work that way
-i extension
Edit files in-place, saving backups with the specified extension. If a zero-length extension is given, no backup will be saved.
In this case e is being interpreted as the extension you want to save your backups with. So all your original files will be backed up with an e appended to their names.
In order to provide a zero-length extension, you need to use -i ''.
Note: Unlike -i<your extension>, -i'' won't work. You need to have a space character between -i and '' in order for it to work.
Removing the -e flag results in an unterminated substitute pattern error.
When you remove the e immediately following -i, i.e.
sed -i 's/ :(float)//g' *
s/ :(float)//g will now be interpreted as the extension argument to i flag. And the first file in the list of files produced by shell expansion of * is interpreted as a sed function (most probably s/regular expression/replacement/flags function) You can verify this by checking the output of
sedfn=$(echo * | cut -d' ' -f1); [[ ${sedfn:0:1} == "s" ]]; echo $?
If the output of the above chain of commands is 0, our assumption is validated.
Also in this case, if somehow the first filename qualifies as a valid s/regular expression/replacement/flags sed function, the other filenames will be interpreted as regular files for sed to operate on.
sed -i -e 's/ :(float)//g' *
Check to see if you have any odd filenames in the directory.
Here is one way to duplicate your error:
$ touch -- "-e s:x:"
$ ls
-e s:x:
$ sed -i "s/ :(float)//g' *
sed: -e expression #1, char 5: unterminated `s' command
One way to protect against this is to use a double dash to terminate the options to sed when you use a wild card:
$ sed -i "s/ :(float)//g' -- *
You can do the same thing to remove the file:
$ rm "-e s:x:"
rm: invalid option -- 'e'
$ rm -- "-e s:x:"