The easiest portable way to do this is:
printf '%s\n' %s/e//g x | ex file
This avoids error conditions discussed below.
One of the advantages of
ex as opposed to Vim is that
ex is guaranteed by POSIX.
If you're in the sysadmin world and you need to script automated edits to text files (e.g. configuration files to be edited across thousands of different remote servers), you want to use something portable. Perl is great but not portable—and it's overkill for very simple file edits.
awk are both guaranteed by POSIX, but they're not designed for in-place file editing. (
sed has a
-i switch in some implementations such as GNU
sed to allow for in-place file editing, but for portable scripting that option shouldn't be relied upon as it is not in the POSIX standard for
The correct tool for the job is
For your example, removing all instances of the letter "e" from the file, the
ex command is simple (and portable):
ex -sc '%s/e//g | x' file
-s switch starts
ex silently, for batch processing (as opposed to interactive use where messages are printed out to the terminal).
-c switch precedes the command to be run.
The substitute command is as you wrote it.
The vertical bar separates commands to be run sequentially (unless you're using it with the
global command, but we're not.)
x command exits after writing any changes to the file. (It only writes to the file if edits were made, thus preserving the file's timestamp if no edits were necessary.)
There is one major caveat to the above command: If the letter "e" doesn't exist anywhere in the file, the substitute command will fail and the
x command won't be executed. This will leave you staring at a silently running
ex process with no error output, or output of any kind. It's not at all obvious in this case what's happening, but it's actually waiting for you to type in
ex commands. (It's more obvious if you omit the
-s flag, so that you are actually prompted for input with a colon.) Just type
q! to exit in this case.
If I were to actually use this to edit files on remote servers, of course, I would want the command to exit correctly even if there weren't any instances of the letter "e" in the files being edited. Vim has an
e flag for the substitute command which would handle this by suppressing
errors if the regex weren't matched:
ex -sc '%s/e//ge | x' file
But the POSIX way would be to use the
global command to run the
substitute command on all lines matching the given regex—and to not run substitute at all if the regex weren't found:
ex -sc 'g/e/s///g
+%s/e//g, see: How to edit files non-interactively (e.g. in pipeline)?