Skip to content
shellmap

import-csvRead CSV files as pipeable PowerShell objects across all 5 shells

Equivalents in every shell

Bashunix
awk -F, 'NR>1 {print $1}' users.csv

`awk -F,` splits on comma; `NR>1` skips the header row. This is the fast 80% answer but doesn't handle RFC 4180 quoted fields (commas inside `"..."`). For correct parsing of quoted CSV, use `mlr --csv cat users.csv` (Miller) or `csvkit`'s `csvcut -c 1 users.csv`.

Zshunix
awk -F, 'NR>1 {print $1}' users.csv

Same external `awk`. macOS ships BSD awk (older syntax) but the basic `-F`/`NR` pattern works identically. For complex CSV, `brew install miller` or `pip install csvkit`.

Fishunix
awk -F, 'NR>1 {print $1}' users.csv

Same external. Fish's `string split ,` builtin is a built-in alternative for simple line-by-line parsing — `while read -l line; for f in (string split , -- $line); echo $f; end; end < users.csv`.

PowerShellwindows
Import-Csv users.csv | ForEach-Object { $_.name }

Reads the header row and infers property names — `$_.name` accesses the column by name. Returns `[PSCustomObject]` per row. `-Delimiter ";"` for Excel-EU CSV; `-Header col1,col2,...` to override / supply headers when the file has none.

cmd.exewindows
powershell -NoProfile -Command "Import-Csv users.csv | ForEach-Object { $_.name }"

cmd.exe has no CSV reader beyond `for /F "tokens=1,2 delims=," %a in (users.csv) do @echo %a` which doesn't handle quoted fields, headers, or any RFC 4180 edge case. PowerShell shell-out is the only sane option.

Worked examples

Read a CSV and filter rows by column value

Bash
awk -F, 'NR>1 && $3 == "admin" {print $1}' users.csv
PowerShell
Import-Csv users.csv | Where-Object role -eq admin | Select-Object name

Read a header-less CSV with explicit column names

Bash
awk -F, '{print "row "NR": "$1", "$2}' data.csv
PowerShell
Import-Csv data.csv -Header id,name | ForEach-Object { "row $($_.id): $($_.name)" }

Convert every numeric-looking column to an int explicitly

Bash
awk -F, 'NR>1 {age=$2+0; print $1", age="age}' users.csv
PowerShell
Import-Csv users.csv | ForEach-Object { [PSCustomObject]@{name=$_.name; age=[int]$_.age} }

Gotchas

  • **Every column comes back as `[string]`** — including numbers, dates, and booleans. Math on `Import-Csv` output silently string-concatenates: `$_.age + 1` returns `"301"` not `31`. Cast explicitly: `[int]$_.age + 1`. The most common source of "why is my CSV total wrong" PowerShell bugs.
  • Default delimiter is `,` regardless of locale. If your file uses `;` (Excel-EU export) or `\t` (tab-separated), pass `-Delimiter ";"` / `-Delimiter "`t"` — without it, every row becomes a single property holding the whole line.
  • Header-row inference is mandatory — if the file has no header, `Import-Csv` treats row 1 as the header (so the actual first data row becomes inaccessible by name). Use `-Header col1,col2,col3` to supply names; this also makes the file's row 1 become a normal data row.
  • Whole file loads into memory before piping starts — fine for MB-scale CSVs, painful for GB-scale. For streaming, fall back to `Get-Content -ReadCount 1000` + `ConvertFrom-Csv` per chunk, or use `Microsoft.VisualBasic.FileIO.TextFieldParser` directly.
  • Encoding: pwsh 5.1 defaults to `default` (Windows-1252) — non-ASCII data corrupts. Pass `-Encoding utf8`. pwsh 6+ defaults to `utf8NoBOM`. Files with a UTF-8 BOM and PS 5.1 `-Encoding utf8` will include the BOM as part of the first column name (`<U+FEFF>name` instead of `name`) — strip the BOM with `dos2unix` or re-save the source.

WSL & PowerShell Core notes

pwsh`Import-Csv` is identical across platforms (since pwsh 6+). The 5.1 quirks (string-only columns, default Windows-1252 encoding, mandatory `-NoTypeInformation` on the `Export-Csv` other side) are well-known — write `[int]$_.col` / `-Encoding utf8` defensively for cross-version scripts.
WSL`Import-Csv /mnt/c/data/users.csv` from pwsh on Windows reads the Windows-side file; `pwsh.exe -c` invoked from WSL bash does the same. CRLF line endings on Windows-side files are handled transparently — no `dos2unix` needed.

Common tasks using import-csv

Related commands