I have a csv file which is of roughly the following format,

name image wht type zt dir
sally sally.fits wht.fits map 100 /users/

but with many more rows than shown in this example.

I am trying to remove the first occurrence of the word subset '.fits' from every single row in the file.

So for this example, it would change sally.fits to sally but leave wht.fits untouched.

I know to remove the first occurrence of a word in every file and/or replace it with another can be done with,


and so I tried amending this command as such,


where %s applies it to every line but I omit /g as I want to remove .fits only the first time it appears on every row (not every occurrence). The \ escapes the dot and nothing after the final / as I don't want to replace it with anything. This was based on a couple other SO posts but this just gave an error saying the combination was not found.

The files are small enough that I can manually delete the combinations but out of curiosity, would anyone know how to go about doing this? or can see where I've gone wrong? any insight would be much appreciated.

  • I turned my earlier comments into an answer. However, you could still edit your question and paste a line or two of your actual CSV file so we can have a look at it.
    – Friedrich
    Commented Mar 22 at 12:11

2 Answers 2


Your approach is valid. This is a textbook example on how to use :substitute.

The command


(the trailing slashes can be omitted) will remove the first ".fits" in each line of the buffer.

The actual solution

OP commented that the :substitute command only worked if the trailing slashes weren't omitted. Apparently only



All the stuff below is me trying to troubleshoot a problem that never existed. I'll leave it around for your amusement.

Since it's not working - and assuming you did not manage to break :substitute in your Vim - the fault must be with the CSV file rather than with the command. I think ".fits" in your command does not match ".fits" as it's in the file.

Three approaches on how to find the error are detailed below. Each would work on their own but you can also combine them.

Highlight search results

An easy way to see if your search pattern is correct is to :set incsearch which will highlight matches as you type and before you actually run the command.

:set incsearch

If you mistype, the highlight will be gone and you can go back and fix it.

Copy and paste into the command

You could also copy ".fits" into your command line by first yanking it. Place your cursor on the dot starting ".fits" and press yE. Then start typing the command as :%s/ and put ".fits" there with Ctrl-R". Run the command.
In short, that's:


No matter how ".fits" was actually spelled, it will be removed.

Check the spelling

It's also possible to inspect the characters in your CSV file as laid out in the answer to See the Unicode code point of the current character. You can use ga on each character of ".fits" to see if it fits (sorry for that) the ASCII range (0 to 127). For example, there's the fi ligature that will look like "fi" - well, it should - but is one character, not two.

Can you spot the difference: fififififififi?

A note on finding :help

In your question you say your command was "based on a couple other SO posts". That's one way to learn Vim but you could also read :help :s which contains the reference on how to use the :substitute command. Having the documentation all in one place right in front of you might be easier than gathering bits and pieces scattered all over the internet.

  • 1
    Thank you for this answer and for detailing how to go through 'debug' this issue - I followed the steps and it now works! I don't understand why adding the extra slash at the end seems to fix it but happy to know how to go about doing this. The :set incsearch is also very useful to know about so thanks for that too!
    – shram
    Commented Mar 22 at 13:53
  • @shram do you perhaps use an old version of Vim? I don't exactly remember when the trailing slashes were made optional but I can't be that long ago. It's funny how I wrote an elaborate answer and in the end it was something completely different (or maybe they have always been optional and I just didn't know it).
    – Friedrich
    Commented Mar 22 at 13:56
  • I couldn't find a relevant change going back to 2004, but I only tried a handful of log searches; I didn't try to bisect.
    – D. Ben Knoble
    Commented Mar 22 at 18:20
  • @D.BenKnoble thanks for going through that effort. I came to the same conclusion. Isn't it amazing how I helped to solve a problem despite my flawed reasoning and my ignorance? I still don't get how the trailing slashes should make a difference.
    – Friedrich
    Commented Mar 22 at 18:48

I would do:


The :g command apply a command to all the lines that fit a pattern.

In this example it runs the substitution command s/\.fits// on all the line that match the pattern \.fits

Remark: but indeed your approach is also good and %s/\.fits// gives the same result.

  • Why not use the e flag on substitute?
    – D. Ben Knoble
    Commented Mar 21 at 23:22
  • Thanks for your answer Vivian! I appreciate it - the command you posted also works so thank you again for taking the time out to respond to my question. Its helpful to know for future work
    – shram
    Commented Mar 22 at 13:54
  • 1
    You are welcome. Thanks for the feedback :-) Welcome to Vim! Commented Mar 22 at 14:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.