Skip to main content

Editing Content Advanced

Beyond single-cell edits, VisiData supports regex-based bulk replace, incremental value generation, macros for repeated workflows, and CommandLog editing for precise replay control.

Learning Focus

Focus on regex replace (*) for pattern-based data cleaning and incremental columns (i) for generating sequences — two of the most time-saving bulk editing operations.

Regex Replace on a Column

Use * to create a derived column that replaces a pattern with a new value (non-destructive):

* search<Tab>replace create new column replacing regex with text
g* search<Tab>replace modify current column for all selected rows (in-place)
gz* search<Tab>replace modify all visible columns for selected rows

Example — normalize status values:

# Move to 'status' column
g*
# Enter: active<Tab>ACTIVE
# All 'active' cells in 'status' become 'ACTIVE' for selected rows

Example — strip port from hostname:

# Move to 'endpoint' column
*
# Enter: :\d+<Tab>
# Creates new column without port numbers: host:8080 → host

Incremental Values

i add column with incremental integer values (1, 2, 3...)
gi set current column for selected rows to incremental values
zi <step> add column with values at given increment step
gzi <step> set current column for selected rows at given step

Example — add a row ID column:

# Move to leftmost position
i
# Name it: row_id
# A new column appears: 1, 2, 3, 4...

Macros

Macros record a sequence of keystrokes and replay them with a single key.

m <keystroke> start recording macro; press same key again to stop
gm open Macro Index (view all recorded macros)

Example — create a macro to frequency-table the current column and return:

m f # start recording, bound to 'f'
Shift+F # open frequency table
q # return to source sheet
m f # stop recording
# Now pressing f will do: Shift+F then q
warning

Macros override existing keybindings. Use uncommon keys (e.g., function keys or uppercase letters that are not already used) to avoid conflicts.

CommandLog Editing (Shift+D)

The CommandLog records every action taken in VisiData as a replayable .vdj file.

Shift+D # open CommandLog for current sheet
gD # open global CommandLog (all commands)
zD # open CommandLog with parent sheet commands removed

# Inside CommandLog:
x # replay command at current row
gx # replay entire CommandLog
^C # abort replay
Ctrl+S # save CommandLog to .vdj file

Use case — document a data cleaning workflow:

# Perform your data cleaning steps interactively
# Press Shift+D to view the recorded commands
# Press Ctrl+S → save as /tmp/clean_workflow.vdj

# Later, replay on a new file:
vd --play clean_workflow.vdj --batch newfile.csv -o cleaned.csv

Joining / Appending Sheets

& append/merge top two sheets in the sheet stack
g& append ALL sheets in the stack

Join types available when prompted:

TypeBehavior
innerKeep only rows matching keys on ALL sheets
outerKeep all rows from first sheet
fullKeep all rows from all sheets (union)
diffKeep rows NOT in all sheets
appendCombine all rows from all sheets
extendCopy first sheet, extend with columns from others
mergeAll rows from first, update empty cells from second

Transposing a Sheet

T open a transposed sheet (rows become columns)

Useful for wide datasets where columns represent time periods.

Practical Use Cases

Normalize Status Labels

vd /tmp/servers.csv
gs # select all rows
g*
# Enter: standby<Tab>STANDBY
# All 'standby' values → 'STANDBY' for selected rows

Generate Row IDs for Import

vd /tmp/data.csv
# Move cursor to first column
i
# Name: id
# Rows now have sequential IDs: 1, 2, 3, ...
Ctrl+S
# Save as: /tmp/data_with_ids.csv

Document and Replay Data Cleaning

# Open source file
vd /var/www/html/exports/raw_orders.csv

# Perform cleaning steps interactively:
# 1. Cast 'amount' to float: move cursor, press %
# 2. Delete null rows: z| amount is None → gd
# 3. Rename 'amt' column to 'amount'

# Save CommandLog
Shift+D
Ctrl+S
# Save as: /tmp/clean_orders.vdj

# Replay next time:
vd --play /tmp/clean_orders.vdj --batch new_orders.csv -o cleaned_orders.csv

Troubleshooting Matrix

ProblemCauseFix
Regex replace matches nothingRegex doesn't matchTest regex with / search first
i creates column at wrong positionCursor on wrong columnMove cursor left first
Macro conflicts with existing keyKey already boundUse gm to check, choose different key
CommandLog replay failsSheet structure changedRe-record from scratch

Hands-On Practice

vd /tmp/servers.csv

# 1. gs → select all
# 2. g* → type: active<Tab>ACTIVE → confirm
# 3. Press U to undo
# 4. Press i → add incremental ID column named 'id'
# 5. Press Shift+D → view recorded commands
# 6. Press q → return to sheet
# 7. Press Ctrl+S → save as /tmp/servers_advanced.csv

What's Next