Sed error - unterminated substitute pattern

I am in a directory with files consisting of many lines of such lines:

98.684807 :(float) 52.244898 :(float) 46.439909 :(float) 

and then the line that completes:

 [chuck]: cleaning up... 

I am trying to exclude :(float) from each file (but leave the number), and also remove this cleanup ....

I can get:

 sed -ie 's/ :(float)//g' * 

but it creates files that store old files. Removing the -e flag results in an error without changing the pattern.

The same goes for:

 sed -ie 's/[chuck]: cleaning up...//g' * 

Thoughts?

+7
sed
source share
6 answers
 sed -i '' -e 's/:(float)//' -e '/^.chuck/d' * 

This way you tell sed not to save the copy (extension of the backup with a zero length to -i ) and to specify sed commands separately.

+11
source share
 sed -ie expression [files...] 

equivalent to:

 sed -ie -e expression [files...] 

and both mean applying the expression to the files, overwriting the files, but saving the old files with "e" as the backup suffix.

I think you want: sed -i -e expression [files ...]

Now, if you get an error message, there should be something wrong with your expression .

+3
source share

your numbers are separated by : (float) . Therefore, you can use awk / cut to get your numbers. Its easier than 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 
+3
source share
 sed -i -e 's/ :(float)//g' * 
+1
source share

Check if you have any odd file names in the directory.

Here is one way to duplicate your error:

 $ touch -- "-es:x:" $ ls -es: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 break sed options when using a wild card:

 $ sed -i "s/ :(float)//g' -- * 

You can do the same to delete the file:

 $ rm "-es:x:" rm: invalid option -- 'e' $ rm -- "-es:x:" 
+1
source share

Decision:

sed -i '' 's/ :(float)//g' *

sed -i '' 's/[chuck]: cleaning up...//g' *

Explanation:

I can get:

 sed -ie 's/ :(float)//g' * 

but creates files that store old files.

This is because the sed i flag should work this way

-i extension

Edit files in place, saving backups with the specified extension. If the extension is set to zero, the backup will not be saved.

In this case, e interpreted as the extension with which you want to keep your backups. This way all your source files will be copied using e added to their names.

To provide a zero-length extension, you need to use -i '' .

Note Unlike -i<your extension> , -i'' will not work. In order for it to work, you need to have a space between -i and. ''


Removing the -e flag results in an unchanged error.

When you delete e immediately after -i , i.e.

sed -i 's/ :(float)//g' *

s/ :(float)//g will now be interpreted as an extension argument for flag i . And the first file in the list of files created by the * shell extension is interpreted as a sed function (most likely s/regular expression/replacement/flags ). You can verify this by checking the output

sedfn=$(echo * | cut -d' ' -f1); [[ ${sedfn:0:1} == "s" ]]; echo $?

If the output of the above sequence of commands is 0 , our assumption is checked.

Also in this case, if somehow the first file name qualifies as a valid s/regular expression/replacement/flags sed function, the other file names will be interpreted as normal sed files to work with.

+1
source share

All Articles