2

I am trying to write a command along the lines of the following:

vim -c "XXXXXX" myFile

Instead of the "XXXXX" I want to supply some commands to vim to add some text to an arbitrary point in the file, both by specifying an exact line number and, in a different scenario, by searching for a specific line and then insert on the line above.

What I am trying to do is a sort of clever "append" where I can append lines to a code block or function inside a script. Ultimately I am aiming to have a setup script which will go and alter maybe a dozen system files.

Ideally it would only involve one -c flag and ideally it would be readable to anyone that can understand normal mode commands - in my head I was originally thinking something like "ggjjjiInsertingOnLine4:wq" once I can get it into normal mode.

Edd
  • 141
  • 5
    You should have a look if sed or awk might not be more suited for this task. Vim was designed for interactive use in contrast to sed and awk. Nonetheless, this can surely be accomplished with vim. – Marco Oct 15 '14 at 20:02
  • Could you do something like vim +33G +r/path/to/somefile +wq /path/to/file to insert the contents of somefile at line 33 of file? – DopeGhoti Oct 15 '14 at 20:06
  • I think you are selecting the wrong tool to use here. Yes, you might be able to do this somehow. But, I might suggest that you look at using any of 'ed', 'sed' or even 'awk' maybe in a small script so you can save the before and after versions. – mdpc Oct 15 '14 at 20:32
  • I appreciate other utilities could accomplish this. Advantages of using vim could be preserving the files undo history or automating functions already implemented in vimscript. – Edd Oct 15 '14 at 22:01

1 Answers1

6

Command line ranges can be use to select a specific line that needs to be edited. Then substitute pattern can be used to perform the edit (append).

For example, to append text "hi" at the begining of line 3:

vim -c "3 s/^/hi/" -c "wq" file.txt

To append text "hi" at the end of line 3:

vim -c "3 s/$/hi/" -c "wq" file.txt

To find more options and explanations:

vim -c "help cmdline-range"

Some more examples

To find a search string "hi" and append string " everyone" on line 3:

vim -c "3 s/\(hi\)/\1 everyone/" -c "wq" file.txt

To find a search string "hi" and prepend a string "say " on line 3:

vim -c "3 s/\(hi\)/say \1/" -c "wq" file.txt

In case the line number is not known, To append first occurrences of string "hi" on every line with " all":

vim -c "1,$ s/\(hi\)/\1 all/" -c "wq" file.txt

To append all occurrences of string "hi" on every line with " all":

vim -c "1,$ s/\(hi\)/\1 all/g" -c "wq" file.txt

For more info about substitutions:

vim -c "help substitute"
  • Thank you this definitely covers one use case. If you include examples for finding, then inserting text before or after the search string I will mark your answer as correct. – Edd Oct 15 '14 at 22:02
  • Thank you, added the extra examples to insert the text after and before the search string. – bonifatio Oct 16 '14 at 14:03
  • Excellent I will use something like "1,$ s/(something)/lineabove\r\1/" to prepend text and then add a new line. Great answer. – Edd Oct 16 '14 at 19:39
  • You're a lifesaver, Edd. All these years of using vi/Vim, I never knew about the -c switch. I've been struggling with a DOS batch file where I'm doing a fairly complex substitution that covers multiple lines. I've tried using the msys version of sed, but I can't get it to handle the newlines properly. (G)vim, however works, but I've been opening the file and issuing the command manually (er, pasting it) daily, for a few weeks, now. Other priorities have kept getting in the way of fixing the problem properly and I need to make this batch file easy to use for someone else. Thanks! – Bob Feb 13 '19 at 00:33
  • is there an equivalent to w fname.txt where instead of 'w' it actually appends instead of overwrites? – Robin Jun 19 '20 at 10:50