Skip to content
100% in your browser. Nothing you paste is uploaded — all processing runs locally. Read more →

Generating UUIDs from the command line

On this page
  1. macOS / Linux
    1. uuidgen (preinstalled on macOS, in util-linux on most distros)
    2. /proc/sys/kernel/random/uuid (Linux only)
    3. openssl (preinstalled almost everywhere)
    4. python3 -c
    5. node -e
  2. Windows
    1. PowerShell
    2. CMD
    3. Windows Subsystem for Linux
  3. Bulk generation
    1. Generate N UUIDs
    2. Generate as CSV
    3. Generate v7 in bulk (cross-platform)
  4. Validation from the shell
  5. Extracting a v7 timestamp from the shell
  6. Aliases worth setting
  7. Common pitfalls
  8. Cheat sheet
  9. Try the tools

You don’t need a website (or this one) to generate a UUID. Every modern OS ships with a tool. Here’s the cheatsheet for every common shell, plus how to bulk-generate, verify, and extract timestamps.

macOS / Linux

uuidgen (preinstalled on macOS, in util-linux on most distros)

uuidgen
# 0E6F1B8C-2C33-4F1F-9C0B-2A3D4E5F6A7B   (uppercase on macOS)

For lowercase:

uuidgen | tr 'A-Z' 'a-z'
# 0e6f1b8c-2c33-4f1f-9c0b-2a3d4e5f6a7b

Apple’s uuidgen does v4 only. GNU uuidgen (Linux) supports more:

uuidgen --random      # v4 (default)
uuidgen --time        # v1
uuidgen --md5  --namespace @url  --name "https://example.com"  # v3
uuidgen --sha1 --namespace @url  --name "https://example.com"  # v5

/proc/sys/kernel/random/uuid (Linux only)

cat /proc/sys/kernel/random/uuid

Always lowercase, always v4, no dependency on util-linux.

openssl (preinstalled almost everywhere)

openssl doesn’t have a UUID command, but it can produce 16 random bytes that you format yourself:

openssl rand -hex 16 | sed 's/^\(.\{8\}\)\(.\{4\}\)\(.\{3\}\)\(.\{1\}\)\(.\{1\}\)\(.\{3\}\)\(.\{12\}\)/\1-\2-4\4-\5\6-\7/' \
  | sed 's/^\(.\{14\}\)\(.\)\(.\)/\1\2\3/' \
  | awk '{ print substr($0,1,19) "-" substr($0,20,1) substr($0,21,4) "-" substr($0,25) }'

That’s ugly. Use uuidgen if it’s available; reach for openssl only when you’re on a barebones container with neither uuidgen nor a Python interpreter.

python3 -c

python3 -c 'import uuid; print(uuid.uuid4())'
python3 -c 'import uuid; print(uuid.uuid7())'        # Python 3.13+
python3 -c 'import uuid; print(uuid.uuid5(uuid.NAMESPACE_URL, "https://example.com"))'

Python 3.13+‘s uuid7() is the easiest way to get a v7 UUID at the shell.

node -e

node -e 'console.log(crypto.randomUUID())'

Works in Node 14.17+. The crypto module is global — no require needed.

Windows

PowerShell

[guid]::NewGuid()
# Guid
# ----
# 0e6f1b8c-2c33-4f1f-9c0b-2a3d4e5f6a7b

To get just the string:

[guid]::NewGuid().ToString()

For uppercase / formatted:

[guid]::NewGuid().ToString("N")    # no hyphens
[guid]::NewGuid().ToString("B")    # {braces}

CMD

CMD has no built-in UUID. Use PowerShell:

powershell -Command "[guid]::NewGuid().ToString()"

Or call uuidgen.exe from Git Bash / WSL.

Windows Subsystem for Linux

Same commands as Linux above. WSL ships with uuidgen in Ubuntu and most other distros.

Bulk generation

Generate N UUIDs

# 100 UUIDs, one per line
for i in $(seq 1 100); do uuidgen; done | tr 'A-Z' 'a-z'

# Faster on Linux — read from /proc directly
for i in $(seq 1 100); do cat /proc/sys/kernel/random/uuid; done

# Python — fastest for large batches
python3 -c 'import uuid; [print(uuid.uuid4()) for _ in range(10000)]'

# Node
node -e 'for(let i=0;i<10000;i++) console.log(crypto.randomUUID())'

For tens of thousands of UUIDs, the Python and Node one-liners are 10–100× faster than looping uuidgen in shell.

Generate as CSV

echo "uuid"                                  # header
python3 -c 'import uuid; [print(uuid.uuid4()) for _ in range(10000)]'

Or one line:

{ echo uuid; for i in $(seq 1 10000); do cat /proc/sys/kernel/random/uuid; done; } > uuids.csv

Generate v7 in bulk (cross-platform)

python3 -c '
import uuid
for _ in range(10000):
    print(uuid.uuid7())
'

Requires Python 3.13+. For older Python, install uuid-utils:

pip install uuid-utils
python3 -c 'import uuid_utils; [print(uuid_utils.uuid7()) for _ in range(10000)]'

Validation from the shell

# Test a value
echo "0e6f1b8c-2c33-4f1f-9c0b-2a3d4e5f6a7b" | grep -qE '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' && echo valid || echo invalid

# As a function
is_uuid() {
  echo "$1" | grep -qE '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'
}
is_uuid "0e6f1b8c-..." && echo "✓"

Extracting a v7 timestamp from the shell

v7_to_time() {
  local id="$1"
  local hex="${id//-/}"            # strip hyphens
  local ts_hex="${hex:0:12}"       # first 12 hex = 48 bits = ms
  local ms=$((16#$ts_hex))
  date -u -d "@$((ms / 1000))" "+%Y-%m-%d %H:%M:%S UTC" 2>/dev/null \
    || date -u -r "$((ms / 1000))" "+%Y-%m-%d %H:%M:%S UTC"
}

v7_to_time "01928a47-3b30-7c5e-9d1a-f0b8c4a7e923"
# 2024-10-09 21:32:30 UTC

The first date form is GNU (Linux); the second (-r) is BSD (macOS). The function tries one then the other.

Aliases worth setting

In ~/.zshrc or ~/.bashrc:

alias uuid="uuidgen | tr 'A-Z' 'a-z' | tee >(pbcopy)"      # macOS — also copies to clipboard
alias uuid="cat /proc/sys/kernel/random/uuid"              # Linux

Then uuid produces a fresh UUID and (on macOS) copies it to the clipboard. Saves a remarkable amount of context-switching.

Common pitfalls

Cheat sheet

NeedCommand
One v4 (macOS / Linux)uuidgen
Lowercaseuuidgen | tr 'A-Z' 'a-z'
One v4 (Linux only, no util-linux)cat /proc/sys/kernel/random/uuid
One v4 (Windows)[guid]::NewGuid().ToString()
One v7python3 -c 'import uuid; print(uuid.uuid7())'
Bulk Nfor i in $(seq 1 N); do uuidgen; done
Validategrep -qE '^[0-9a-f]{8}-[0-9a-f]{4}-...'

Try the tools