开发者

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:"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜