2

I want do a series of "search and replace" on a given file, say file.txt. For example,

s/foo/bar/g
s/abc/xyz/g
s/pqr/lmn/
g/string-delete/d 

and so on.

How shuld I write all these actions in a script file and then run them on a single go on the target file.txt to save it to newfile.txt?

I saw this post Search and replace variables in a file using bash/sed but somehow couldn't get it to work for me.

Edit: i would prefer a vim/ed based solution Thanx tempora

Community
  • 1
  • 1
Tem Pora
  • 2,043
  • 2
  • 24
  • 30

4 Answers4

6

Use :source {file} to run a vim script.

Save your commands to a file, e.g. commands.vim. Then open up the buffer that you want to apply the commands to and source the commands.vim file like so:

:so commands.vim

Note: :so is short for :source

For more help see:

:h :so
Peter Rincker
  • 43,539
  • 9
  • 74
  • 101
3

You can put the commands in a file and pass it to sed -f:

$ cat commands.sed↵
s/foo/bar/g
s/abc/xyz/g
s/pqr/lmn/
/string-delete/d
$ sed -f commands.sed my_input.txt > my_output.txt↵

or even make it a shell-script

$ cat munge.sed↵
#!/bin/sed -f
s/foo/bar/g
s/abc/xyz/g
s/pqr/lmn/
/string-delete/d
$ chmod a+x commands.sed↵
$ ./munge.sed my_input.txt > my_output.txt↵

Finally, you can pass the commands directly to sed(1) as a one-liner:

$ sed -e "s/foo/bar/g" -e "s/abc/xyz/g" -e "s/pqr/lmn/" -e "/string-delete/d" my_input.txt > my_output.txt↵
Gumnos
  • 403
  • 3
  • 7
2

You could just write a function wrap those commands, and call the function.

Note !!

the function below is an example, I added % in front of your s cmd. because I guess you want to do substitution on whole buffer, not on "current" line. But you have to be careful, in this way, the previous replaced result could be replaced again by latter command, if the latter pattern matched. just adjust it as your needs.

e.g. think about:

text: fooc you have %s/foo/ab/g and %s/abc/def/g

fun! ExecThem()
    %s/foo/bar/g
    %s/abc/xyz/g
    %s/pqr/lmn/g
    g/string-delete/d
endf

source the function, then

:call ExecThem()

will do the job.

you could of course create a command for that:

command Mybatch call ExecThem()
Kent
  • 189,393
  • 32
  • 233
  • 301
  • Why use the `execute` command? `%s/foo/bar/g` is an ex command just like `execute`. – Peter Rincker May 02 '13 at 13:51
  • @PeterRincker I copied some lines from one of my existing function, there I had variables in the `s/../../`, I removed variables and quotes, but didn't take the `exec` out.. – Kent May 02 '13 at 14:01
0

An easy and quick way would be to copy the commands into a register with "ay and then run the register as a macro with @a.

Facundo Casco
  • 10,065
  • 8
  • 42
  • 63
  • I prefer the function way, or an additional script file (like @Peter's answer) is better than macro in this case. not because I gave an answer like that. think about after two days, we found we need add one more `s/../../` line into that "register", oh, after another two days, we found out we want to change the 1st line into `%s/foo/baz/g`, and after another 3 days.... you see what I mean. – Kent May 02 '13 at 14:06
  • that's why I said "easy and quick", it was meant as something you need to do once or a couple of times in the same day and then forget about it. It is good to have alternatives to choose from – Facundo Casco May 02 '13 at 14:27