Skip to content
shellmap

export-csvWrite PowerShell objects to a CSV file with header row across all 5 shells

Equivalents in every shell

Bashunix
echo -e "name,age\nalice,30\nbob,25" > users.csv

Bash has no built-in CSV writer — `printf` or `echo -e` with literal `\n` is the lowest-common-denominator approach. For programmatic CSV, `mlr --c2t cat` (Miller) or `csvkit`'s `csvjson --reverse` give safer escaping (quotes around fields containing commas / newlines / quotes per RFC 4180).

Zshunix
echo -e "name,age\nalice,30\nbob,25" > users.csv

Same approach. macOS `echo` accepts `-e` since Big Sur (bash 3.2 builtin); on older macOS, prefer `printf "name,age\nalice,30\n"` for portability. Install `mlr` via `brew install miller` for safer typed CSV emission.

Fishunix
printf "name,age\nalice,30\nbob,25\n" > users.csv

Fish has no `echo -e` (it doesn't interpret backslash escapes by default). Use `printf` for literal newlines, or `string join \n` if generating lines from a fish list.

PowerShellwindows
$users | Export-Csv -Path users.csv -NoTypeInformation

`-NoTypeInformation` suppresses the `#TYPE System.Management.Automation.PSCustomObject` header line — on pwsh 6+ this is the DEFAULT, but on Windows PowerShell 5.1 the type header is included by default and breaks every other CSV consumer (Excel, pandas, csvkit). Always pass the flag for portable scripts.

cmd.exewindows
powershell -NoProfile -Command "$users | Export-Csv users.csv -NoTypeInformation"

cmd.exe has no CSV writer. PowerShell shell-out is the standard answer. For pure-cmd one-offs, `echo name,age > users.csv` + `echo alice,30 >> users.csv` works but doesn't handle quoting or escapes.

Worked examples

Export a list of running processes to CSV

Bash
ps -eo pid,user,cmd --no-headers | awk 'BEGIN{print "pid,user,cmd"} {print $1","$2","$3}' > procs.csv
PowerShell
Get-Process | Select-Object Id, ProcessName, CPU | Export-Csv procs.csv -NoTypeInformation

Append to an existing CSV without rewriting the header

Bash
echo "carol,28" >> users.csv
PowerShell
$newUser | Export-Csv users.csv -Append -NoTypeInformation

Use a semicolon delimiter (Excel-EU friendly)

Bash
mlr --ocsvlite --ofs ";" cat users.json > users.csv
PowerShell
$users | Export-Csv users.csv -Delimiter ";" -NoTypeInformation

Gotchas

  • **Windows PowerShell 5.1 mandatorily emits `#TYPE …` as line 1** unless `-NoTypeInformation` is passed — every downstream tool (Excel, pandas, R) treats it as garbage. pwsh 6+ flipped the default to omit, but the flag is still accepted for back-compat. Make `-NoTypeInformation` muscle memory on 5.1 scripts.
  • `-Append` does NOT check that the header row matches the existing file — if the appended objects have different / extra properties, you get rows with shifted columns. Always materialise the target schema first (`Select-Object Id, Name, ...`) before piping to `-Append`.
  • Default encoding on Windows PowerShell 5.1 is `default` (Windows-1252 on US locales, MBCS elsewhere) — non-ASCII data round-trips lossily. Pass `-Encoding utf8` (or `utf8NoBOM` on pwsh 6+) for safe Unicode. pwsh 6+ defaults to `utf8NoBOM`.
  • `-UseQuotes` (pwsh 7+) controls quoting: `Never` / `Always` / `AsNeeded` (default — quotes only fields containing delimiter / newline / quote). 5.1 + 6.x always quote-every-field — Excel-EU CSV consumers sometimes choke on this.
  • Concurrent `-Append` from multiple processes is NOT safe — the cmdlet opens the file with default share flags and you get interleaved-row corruption. For concurrent writers, serialise via a queue (Service Bus, file lock) or write per-process files and combine afterwards.

WSL & PowerShell Core notes

pwshOn pwsh 6+, default encoding is `utf8NoBOM`, `-NoTypeInformation` is the default, and `-UseQuotes` is available — all 5.1-quirks gone. `Export-Csv` works identically on Windows / Linux / macOS pwsh. The line-ending is `\r\n` on Windows, `\n` on Linux/macOS — for cross-OS-identical output, post-process with `-replace "\r\n", "\n"`.
WSLFrom WSL bash, `pwsh.exe -c "$users | Export-Csv /mnt/c/data/users.csv -NoTypeInformation"` writes to the Windows filesystem and produces Windows line endings. For Linux-tool consumers, pipe through `dos2unix` after.

Related commands