There’s More Than One Way to Edit Text

While refactoring my current project, I needed to edit some fixture files that were used to populate data in a couple of UI components. Before diving straight in, I looked at these files and wondered how many ways there were to edit them.

How many different techniques and tools are available to reach the same end result?

The Problem

As a point of reference, we’ll be editing a file called stateList.js, which contains an array of JavaScript objects that represent each of the 50 states, like so:


export const stateList = [
  {
    name: "Alabama",
    code: "AL"
  },
  {
    name: "Alaska",
    code: "AK"
  },
  {
    name: "Arizona",
    code: "AZ"
  },
  ...
  {
    name: "Wyoming",
    code: "WY"
  }
];

Each of the objects in this stateList array contains two properties: a name and a code. On my project, we no longer needed the code property for our UI component. Each of these objects would have been left with only the name property, which could be better represented by replacing the object with a primitive string. In the end, our stateList looked something like this:


export const stateList = [
  "Alabama",
  "Alaska",
  "Arizona",
  ...
  "Wyoming",
];

My goal was simple. I wanted to discover a handful of different ways to edit the stateList.js file that were faster than making all of the necessary changes manually. Here are a few of the ways I found.

Multiple Cursors

If you’ve used any modern IDE or text editor recently, there’s a good chance it had support for multiple cursors. Multiple cursors are an excellent tool when you need to write the same sentence 10+ times but only feel like typing it once.

Editing a file in VS Code with multiple cursors.

In the case of our stateList example, I was able to select the opening bracket on Line 3 and create additional cursors for every opening bracket in the file. Once the multiple cursors were in place, I made the necessary changes to the first object in the array. The changes were applied to the other 49 simultaneously.

Here are some helpful keybindings if you want to try out multiple cursors in VS Code:

  • Alt+Click – Add cursor at line
  • Ctrl+D / ⌘+D – Add cursor at next occurrence of word
  • Ctrl+Alt+Up / ⌘+Alt+Up – Add cursor above
  • Ctrl+Alt+Down / ⌘+Alt+Down – Add cursor below
  • Ctrl+Shift+L / ⌘+Shift+L – Add cursor at all occurences of word

Find/Replace with Regular Expressions

It turns out that regular expressions are useful for more than form validation! If you haven’t become familiar with them already, I suggest you do so. They are incredibly powerful and can save you quite a bit of time if you know how to use them.

Replacing text with regular expressions in VS Code.

In the example above, I’ve used the following regular expression:

{\n.*name: (.*$)\n.*\n.*

This expression matches each of the individual objects in the stateList array and replaces each of them with $1–this is known as a capture group. A capture group is the part of the regular expression surrounded by parentheses.

In our case, we’re capturing the name of each state so we can replace the matched expression with the captured value.

If you’re interested in learning more about regular expressions, I would suggest taking a look at RegExr or Regex 101.

Vim Macros

I have to say that I am a huge fan of using macros in Vim. A macro is nothing more than a sequence of recorded keystrokes that can be used at a later time.

Editing a file using vim macros in VS Code.

In the example shown here, I recorded a macro that removed all of the text surrounding the name of the state. Then I was able to execute it 50 times in a row, starting on Line 3. Much like the other options I’ve presented so far, Vim macros are extremely helpful once you get comfortable recording the sequence of keystrokes.

Awk

The last option (in this blog) jumps out of the text editor and into the terminal. Having briefly used Awk once or twice while someone told me what to type, I decided to try it out for myself.

For the most part, Awk tends to follow the form:

awk '/expression/ {function}' filename.foo
  • expression – a regular expression used to match words in a given line
  • function – the function(s) to perform on each of the matching lines
  • filename.foo – the file to read

Here’s the Awk command I used to extract the list of state names from the file and copy them to the system clipboard:

awk '/name/ {$1=""; print}' stateList.js | pbcopy

Which Should You Use?

With so many options to choose from, how can you ever decide which one to pick? It boils down to your comfort level with each of the methods and the type of content you’re trying to edit.

If it’s going to take a few minutes to write a regular expression that matches the text you want to replace, it might be better to record a Vim macro or use Awk. The type/size of the file might be another thing to consider since Awk will be much faster than waiting for 10,000 iterations of a Vim macro to finish executing.

Here’s a copy of the stateList.js file if you would like to try some of these methods for yourself. I’m interested to hear about the ways you’ve discovered to edit text.