Automated search and replace can be very handy although there are occasions where a human needs to get involved on some of the decisions. If the search term isn’t unique or appears as part of other words or something like that. When this is the case you’ll want a confirm step where you can approve each replacement before it happens.

With very little work we can achieve this using a combination of vim and grep. I’ll use grep to find the search term and return a list of affected files. Looping over each of these files I can employ a simple vim substitution with the /c (confirmation) flag.

FROM="your search term here"
TO="your replacement here"
FILES=$(grep -rl "$FROM" *)
echo ""
echo "$FROM => $TO"
echo "-----------------------------------------------"
for SUBJECT_FILE in ${FILES//\\n/ } ; do
    echo "$SUBJECT_FILE"
    vim "$SUBJECT_FILE" -c "%s/$FROM/$TO/gc" -c "wq"
echo "-----------------------------------------------"
echo ""
echo "Done!"

The key this little script is the ability to pass vim a string of commands with the -c flag. In this way it is simple to:

  • open a file with vim vim "$SUBJECT_FILE"
  • perform the substitution and -c "%s/$FROM/$TO/gc"
  • then automatically save it before quitting -c "wq".

A simple little hack I use quite often in some of my bash scripts - most recently used to upgrade from Bootstrap v4-alpha.2 to v4.alpha.5 in a project. Between the versions, a fair proportion of CSS class names had been changed so these needed to be updated across the project.

To get the list of all the classes that need to be replaced I used nokogiri (a Ruby HTML parsing library) command line tools. This was executed directly against the bootstrap upgrade guide web site.