Remove PII for Free Without Leaving Google Sheets

By Andrew Apell, creator of Flookup Data Wrangler. Updated

About the author

Andrew Apell is the creator of Flookup Data Wrangler and has built data cleaning tools for Google Sheets since 2018. The method in this post reflects work on large reconciliation tasks with a government team and continued testing with Sheets users.
Every Flookup result described here can be checked in the documentation before purchase.
Read Our Story for the background, or contact the team with any questions about this post, including corrections, unclear steps or use cases we have not covered yet.

Key Takeaways

  • A spreadsheet can find, mask, redact and hash personal data without a separate tool.
  • ISEMAIL and REGEXMATCH identify the columns that need treatment before anything is changed.
  • REGEXREPLACE masks values in a new column, and Find and replace overwrites every match in place.
  • A hash is pseudonymisation, not anonymity, and an unsalted hash of an email is easy to reverse.

Introduction

You need to share a sample of your data with a vendor, a colleague or a support thread. The file works for the task, but it carries emails, phone numbers and IP addresses that have no business leaving your systems.

Scrubbing replaces those values with something that keeps the shape of the data without the person behind it. A spreadsheet has the functions to do it, and every change is visible before the file is shared.

Work on a copy. Scrubbing is destructive once values are pasted over the original column, and a spreadsheet's version history is the only easy way back.


What Counts as Personal Data

Personal data is any value that can point to a person, directly or in combination with another value. In a typical export the obvious ones are these:

Combinations matter as much as single fields. A postcode, a birth date and a job title together can identify a person even when no name appears. Review the file by column, not just by pattern.


Find the Columns That Need Treatment

Before changing anything, measure. ISEMAIL tests whether a value looks like an email address, and SUMPRODUCT counts the matches across a column:

=SUMPRODUCT(--ISEMAIL(A2:A1000))

A count near the number of rows means the column is a contact field and needs treatment. A count of zero means the column is safe from that pattern, though it may still hold a name or an address.

For patterns without a dedicated function, REGEXMATCH does the same job. This count finds values that look like an IPv4 address:

=SUMPRODUCT(--REGEXMATCH(C2:C1000, "\d{1,3}(\.\d{1,3}){3}"))

Put one count per column on a summary tab. The result is a short list of columns to treat, and a record of why each one was chosen.

Run the same counts on the output afterwards. A count that stays the same means the treatment missed the values, which is the failure mode worth catching before the file leaves.


Mask Values with REGEXREPLACE

Masking keeps enough of a value to confirm its format and removes the identifying part. For an email address, keep the domain and replace the local part:

=REGEXREPLACE(A2, "([A-Za-z0-9._%+-]+)@([A-Za-z0-9.-]+)", "***@$2")

The result turns alice@example.com into ***@example.com. The domain survives so the reader can see which organisation the record belongs to, while the mailbox name does not.

Phone numbers and IP addresses are easier to mask digit by digit:

=REGEXREPLACE(B2, "\d", "*")

Applied to an IP address, the pattern keeps the dots and replaces every digit, which preserves the column as a recognisable address without exposing the network. Applied to a phone number, the pattern masks every digit and keeps only the plus sign, because it matches digits and not punctuation.

The formula writes into the cell that holds it. Put it in a new column, check a sample by eye, then copy the result and use Paste special, then Values only, to replace the original column. Delete the helper column afterwards, because a masked value beside the original protects nothing.


Redact Across the Sheet

When the reader needs nothing from a column, remove the value rather than mask it. The quickest way is Find and replace with regular expressions, which works across the whole spreadsheet at once.

Open Edit, then Find and replace, and tick Search using regular expressions. Use this pattern to match any email address:

[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}

Replace it with a marker such as [redacted] and choose Replace all. The same approach works for a phone number pattern or an IP address pattern, one field type at a time.

For a column that should be empty, clear the contents instead. Select the column, press Delete, and confirm that no formula elsewhere depends on it.

Redaction is irreversible in the sheet. Keep the original file, or rely on version history, until the scrubbed copy has been reviewed.


Hash Identifiers with Apps Script

Hashing is the middle option. It replaces a value with a fixed-length digest, so equal inputs produce equal digests and grouping still works, while the original text cannot be read from the output.

Google Sheets has no native hash function. Apps Script provides Utilities.computeDigest, which takes a digest algorithm, a string and a character set:

function hashColumn() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const salt = PropertiesService.getScriptProperties().getProperty("HASH_SALT");
  if (!salt) {
    throw new Error("Set HASH_SALT in the script properties first.");
  }
  const values = sheet.getRange("A2:A1000").getValues();
  const digests = values.map(function (row) {
    if (row[0] === "") {
      return [""];
    }
    const bytes = Utilities.computeDigest(
      Utilities.DigestAlgorithm.SHA_256,
      salt + row[0],
      Utilities.Charset.UTF_8
    );
    const hex = bytes.map(function (byte) {
      return ((byte + 256) % 256).toString(16).padStart(2, "0");
    });
    return [hex.join("")];
  });
  sheet.getRange(2, 2, digests.length, 1).setValues(digests);
}

The function reads column A, hashes each value with a secret salt and writes a 64-character hex digest into column B. Bytes come back as signed numbers, which is why each one is shifted into the 0 to 255 range before conversion.

The salt is stored in Project Settings under Script properties, never in a cell. It is what stops someone with a list of common email addresses from hashing each one and matching your output.

Any spreadsheet that uses the same salt produces the same digests, so two scrubbed files can still be joined on the hashed email. Use a different salt for each sharing context when that link is not wanted.

Replace the column reference and the output range to match your sheet, and clear the output column before a second run.


A Worked Example

A support export holds one row per customer:

email phone ip_address
alice@example.com +254 700 123456 192.168.1.20
bob@example.com +256 701 654321 192.168.1.21

Masking the email local part, every digit in the phone number and every digit in the IP address produces this shareable copy:

email phone ip_address
***@example.com +*** *** ****** ***.***.*.**
***@example.com +*** *** ****** ***.***.*.**

Each digit is replaced one for one, so the octets keep their original length: a single-digit octet becomes one star and a two-digit octet becomes two. If the length itself must not be visible, replace each run of digits with a fixed marker by using the pattern \d+ instead of \d.

The two email values now look identical even though the mailboxes differ. That is the trade a mask makes: the column still proves that an email was present, and it no longer says which one.

For a use case that needs to count repeat customers, hash instead. The two digests stay different, so a pivot table can still count distinct customers without exposing an address.


Troubleshooting Common Issues


What Scrubbing Does Not Do

Scrubbing is a sharing aid, not a guarantee. Three limits are worth stating plainly.

If your data is governed by a policy, review the output against that policy before it moves. The scrubber is the step before the review, not a replacement for it.

Download a fresh copy rather than sharing the workbook. A downloaded CSV contains the current values of the active sheet and does not carry the other tabs, the comments or the history with it.


Share the Shape of the Data, Not the People in It

Sharing a file should not mean sharing the people inside it. A spreadsheet can find the columns that hold personal data, mask the values with REGEXREPLACE, overwrite them with Find and replace, or hash identifiers so grouping still works.

Choose the treatment by what the reader needs. Mask when the format must remain visible, redact when the column can go, and hash when records must still be counted or joined.

When the cleaning step extends beyond personal data, Flookup Data Wrangler standardises the rest of the records inside the same sheet.


Frequently Asked Questions

How do I remove personal data from a CSV in Google Sheets?

Work on a copy of the file. Find the columns that hold personal data, then mask the values with REGEXREPLACE, clear the column, or use Find and replace with regular expressions to overwrite every match. Copy the result to a new file before sharing it.

Is masking reversible?

No. A masked value keeps a fragment such as a domain or the last four digits, and the removed text cannot be recovered from the output. The original column must be deleted before sharing, not just hidden.

Is a hashed email safe to share?

Not on its own. An unsalted hash of an email can be reversed by testing a list of likely addresses. A salted hash raises the effort, but hashed data can still count as personal data under a privacy policy, so treat it as reduced risk rather than anonymity.

Does REGEXREPLACE change the original column?

No. The formula writes the result into the cell that holds it. Keep the formula in a new column, then paste the values over the original column when the result has been reviewed.

Can Google Sheets detect email addresses automatically?

ISEMAIL returns true for a value that looks like an email address. Wrap it in SUMPRODUCT to count the matches in a column and identify which columns need treatment.


Clean the Rest of the Record

Removing personal data is one part of preparing a file to share. Flookup Data Wrangler standardises names, trims stray characters and matches records inside the sheet, so the scrubbed copy is also a clean one.

Install Flookup Data Wrangler from the Google Workspace Marketplace and follow the get-started guide, or see the pricing page for the one-time passes.


Run This Workflow on Your Own Data

Flookup runs inside Google Sheets: fuzzy matching, deduplication, profiling and enrichment on the rows you already have. Free tier from install with no credit card required.

Install Flookup Data Wrangler from the Google Workspace Marketplace, or open the documentation to run the formulas on sample data.


You Might Also Like