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
  • 1
  • 6
  • 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"
bonifatio
  • 76
  • 3
  • 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