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:"
精彩评论