If you’ve spent years on Linux and are now working on Windows, or you’re writing cross-platform documentation and need the PowerShell counterpart for a Unix command, this is the reference page for that.
The tables below cover all major GNU Coreutils commands organized by category. Direct equivalents show the cmdlet and any aliases. For commands with no native equivalent, the closest workaround or recommended tool is noted.
File Content
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
cat |
Concatenate/print files | Get-Content (aliases: gc, cat, type) |
tac |
Print file in reverse | (Get-Content file)[-1..-((Get-Content file).Count)] |
head |
Print first N lines | Get-Content -TotalCount N / Select-Object -First N |
tail |
Print last N lines | Get-Content -Tail N |
od |
Dump file in octal/hex | Format-Hex |
xxd |
Hex dump | Format-Hex |
wc |
Count words/lines/chars | Measure-Object -Line -Word -Character |
nl |
Number lines | $n=1; Get-Content f | % { "$n`t$_"; $n++ } |
pr |
Paginate text for printing | No direct equivalent |
fold |
Wrap long lines | No direct equivalent |
fmt |
Simple text formatter | No direct equivalent |
Examples:
# Print a file
Get-Content .\notes.txt
# Print last 20 lines (like tail -n 20)
Get-Content .\log.txt -Tail 20
# Count lines, words, and characters (like wc -lwc)
Get-Content .\notes.txt | Measure-Object -Line -Word -Character
# Hex dump a file (like xxd or od -x)
Format-Hex .\binary.bin
# Print file in reverse (like tac)
$lines = Get-Content .\notes.txt
$lines[-1..-($lines.Count)]
File Operations
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
cp |
Copy files | Copy-Item (aliases: cp, copy, cpi) |
mv |
Move/rename files | Move-Item (aliases: mv, move, mi) |
rm |
Remove files | Remove-Item (aliases: rm, del, ri) |
rmdir |
Remove empty directories | Remove-Item (alias: rmdir) |
mkdir |
Create directories | New-Item -ItemType Directory (aliases: mkdir, md) |
install |
Copy + set attributes | Copy-Item + Set-ItemProperty |
unlink |
Remove a single file | Remove-Item |
link |
Create hard link | New-Item -ItemType HardLink -Target src |
ln |
Create hard/symbolic links | New-Item -ItemType HardLink or -ItemType SymbolicLink |
touch |
Update timestamps / create file | New-Item; (Get-Item f).LastWriteTime = Get-Date |
truncate |
Truncate or extend file size | $fs = [IO.FileStream]::new('f',[IO.FileMode]::Open); $fs.SetLength(N); $fs.Close() |
shred |
Securely overwrite file | No native; cipher /w: wipes free space only |
split |
Split file into pieces | No direct equivalent (custom scripting needed) |
csplit |
Split on context | No direct equivalent |
Examples:
# Create a directory (like mkdir -p)
New-Item -ItemType Directory -Path .\new\nested\dir -Force
# Create a symbolic link (requires elevated prompt or Developer Mode)
New-Item -ItemType SymbolicLink -Path .\link.txt -Target .\original.txt
# Create a hard link
New-Item -ItemType HardLink -Path .\hardlink.txt -Target .\original.txt
# Touch a file (create if missing, update timestamp if exists)
if (Test-Path .\file.txt) {
(Get-Item .\file.txt).LastWriteTime = Get-Date
} else {
New-Item .\file.txt
}
# Truncate a file to 0 bytes
$fs = [IO.FileStream]::new('.\file.bin', [IO.FileMode]::Open)
$fs.SetLength(0)
$fs.Close()
Directory Listing
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
ls |
List directory | Get-ChildItem (aliases: ls, dir, gci) |
dir |
List directory (like ls) | Get-ChildItem |
vdir |
Verbose list (like ls -l) |
Get-ChildItem | Format-List |
dircolors |
Color setup for ls | No equivalent (use $PSStyle for color customization) |
Examples:
# List files, sorted by last write time descending (like ls -lt)
Get-ChildItem | Sort-Object LastWriteTime -Descending
# Recursive listing (like ls -R)
Get-ChildItem -Recurse
# Only files, no directories
Get-ChildItem -File
# Only directories
Get-ChildItem -Directory
# Show hidden files (like ls -a)
Get-ChildItem -Force
Text Processing
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
sort |
Sort lines | Sort-Object |
uniq |
Filter duplicate lines | Get-Unique; Sort-Object -Unique |
cut |
Cut fields from lines | ($line -split ',')[1]; Select-String |
paste |
Merge lines side-by-side | No direct equivalent (custom scripting) |
join |
Join matching lines from two files | No direct equivalent |
comm |
Compare sorted files line by line | Compare-Object |
tr |
Translate/delete characters | -replace; .Replace(); -creplace |
expand |
Convert tabs to spaces | $s -replace "\t"," " (custom width logic) |
unexpand |
Convert spaces to tabs | No direct equivalent |
shuf |
Shuffle lines randomly | Get-Content f | Sort-Object {Get-Random} |
seq |
Generate number sequence | 1..N; for loop |
numfmt |
Reformat numbers (human-readable) | Custom; [math]::Round(), -f format |
ptx |
Permuted index | No equivalent |
tsort |
Topological sort | No equivalent |
Examples:
# Sort lines alphabetically
Get-Content .\words.txt | Sort-Object
# Sort numerically descending (like sort -rn)
Get-Content .\numbers.txt | Sort-Object { [int]$_ } -Descending
# Remove duplicate lines (like sort -u or sort | uniq)
Get-Content .\list.txt | Sort-Object -Unique
# Cut the second field from a CSV line (like cut -d, -f2)
Get-Content .\data.csv | ForEach-Object { ($_ -split ',')[1] }
# Translate: replace all colons with semicolons (like tr ':' ';')
$text -replace ':', ';'
# Case-sensitive replace (like tr with exact chars)
$text -creplace 'abc', 'xyz'
# Shuffle lines randomly (like shuf)
Get-Content .\list.txt | Sort-Object { Get-Random }
# Generate a sequence (like seq 1 10)
1..10
# Generate a sequence with a step (like seq 0 2 10)
0..10 | Where-Object { $_ % 2 -eq 0 }
# Compare two files, show differences (like comm)
Compare-Object (Get-Content .\file1.txt) (Get-Content .\file2.txt)
Checksums & Hashing
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
md5sum |
MD5 hash | Get-FileHash -Algorithm MD5 |
sha1sum |
SHA1 hash | Get-FileHash -Algorithm SHA1 |
sha224sum |
SHA224 hash | No native SHA224 (use SHA256 as closest) |
sha256sum |
SHA256 hash | Get-FileHash -Algorithm SHA256 |
sha384sum |
SHA384 hash | Get-FileHash -Algorithm SHA384 |
sha512sum |
SHA512 hash | Get-FileHash -Algorithm SHA512 |
b2sum |
BLAKE2 hash | No native equivalent |
cksum |
CRC checksum + byte count | No direct equivalent |
sum |
BSD/SYSV checksum | Get-FileHash (different algorithm) |
Examples:
# SHA256 hash of a file (like sha256sum)
Get-FileHash .\installer.exe -Algorithm SHA256
# Output just the hash string
(Get-FileHash .\installer.exe -Algorithm SHA256).Hash
# MD5 (like md5sum)
Get-FileHash .\file.zip -Algorithm MD5
# Hash all files in a directory
Get-ChildItem .\downloads\ | Get-FileHash -Algorithm SHA256
Get-FileHash outputs an object with Algorithm, Hash, and Path properties. The hash value is uppercase hex with no filename attached. sha256sum appends the filename on the same line. If you need that format:
$h = Get-FileHash .\file.zip -Algorithm SHA256
"{0} {1}" -f $h.Hash.ToLower(), $h.Path
Encoding / Conversion
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
base64 |
Base64 encode/decode | [Convert]::ToBase64String([IO.File]::ReadAllBytes(f)) / [Convert]::FromBase64String(s) |
base32 |
Base32 encode/decode | No native; use .NET or custom function |
dd |
Convert and copy (low-level) | No direct equivalent |
Examples:
# Base64 encode a file (like base64 file.bin)
[Convert]::ToBase64String([IO.File]::ReadAllBytes('.\file.bin'))
# Base64 encode a string
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("hello world"))
# Base64 decode a string
$bytes = [Convert]::FromBase64String("aGVsbG8gd29ybGQ=")
[Text.Encoding]::UTF8.GetString($bytes)
# Base64 decode to a file
[IO.File]::WriteAllBytes('.\output.bin', [Convert]::FromBase64String($encoded))
File Path & Info
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
pwd |
Print working directory | Get-Location (aliases: pwd, gl) |
basename |
Strip path, get filename | Split-Path -Leaf |
dirname |
Strip filename, get directory | Split-Path -Parent |
realpath |
Resolve absolute/canonical path | Resolve-Path |
readlink |
Read symlink target | (Get-Item path).Target |
pathchk |
Validate path portability | Test-Path |
stat |
File metadata/status | Get-Item; Get-ItemProperty |
Examples:
# Get just the filename from a path (like basename)
Split-Path -Leaf "C:\Users\<user>\Documents\report.pdf"
# report.pdf
# Get the directory from a path (like dirname)
Split-Path -Parent "C:\Users\<user>\Documents\report.pdf"
# C:\Users\<user>\Documents
# Resolve a relative path to absolute (like realpath)
Resolve-Path .\..\..\file.txt
# Read where a symlink points (like readlink)
(Get-Item .\mylink).Target
# File metadata (like stat)
Get-Item .\file.txt | Select-Object Name, Length, LastWriteTime, Attributes
# Check if a path exists (like pathchk / test -e)
Test-Path .\file.txt
Permissions & Ownership
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
chmod |
Change file permissions | Set-Acl; icacls (cmd) |
chown |
Change file owner | Set-Acl; icacls /setowner (cmd) |
chgrp |
Change group ownership | Set-Acl (Windows uses ACLs, not POSIX groups) |
chcon |
Change SELinux context | No equivalent (SELinux is Linux-specific) |
runcon |
Run with different SELinux context | No equivalent |
Windows uses Access Control Lists (ACLs) rather than POSIX permission bits, so there’s no one-to-one mapping for chmod’s octal notation. Set-Acl is the PowerShell way, though icacls (a cmd tool available in PowerShell) is often more practical for quick changes:
# Grant a user full control (like chmod 700 for owner)
icacls .\file.txt /grant "$($env:USERNAME):(F)"
# Remove all inherited permissions and set explicit ones
icacls .\file.txt /inheritance:r /grant "$($env:USERNAME):(R,W)"
# Read current ACL
Get-Acl .\file.txt | Format-List
System Information
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
uname |
OS/kernel info | Get-CimInstance Win32_OperatingSystem |
arch |
Machine architecture | $env:PROCESSOR_ARCHITECTURE |
hostname |
Print/set hostname | $env:COMPUTERNAME; Rename-Computer |
hostid |
Numeric host ID | No direct equivalent |
uptime |
System uptime | (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime |
nproc |
Number of CPU cores | $env:NUMBER_OF_PROCESSORS; (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors |
df |
Disk free space | Get-PSDrive; Get-Volume |
du |
Disk usage by directory | Get-ChildItem -Recurse | Measure-Object -Property Length -Sum |
tty |
Print terminal name | No direct equivalent |
stty |
Terminal settings | No direct equivalent |
Examples:
# OS info (like uname -a)
Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, OSArchitecture
# CPU core count (like nproc)
$env:NUMBER_OF_PROCESSORS
# System uptime (like uptime)
$os = Get-CimInstance Win32_OperatingSystem
(Get-Date) - $os.LastBootUpTime
# Disk free space (like df -h)
Get-PSDrive -PSProvider FileSystem | Select-Object Name, Used, Free
# Disk usage of a directory (like du -sh .)
(Get-ChildItem . -Recurse | Measure-Object -Property Length -Sum).Sum
User & Session Info
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
whoami |
Current user name | $env:USERNAME; whoami |
id |
User/group IDs | [Security.Principal.WindowsIdentity]::GetCurrent() |
logname |
Login name | $env:USERNAME |
who |
Who is logged in | query user; Get-CimInstance Win32_LoggedOnUser |
users |
Logged-in usernames | query user; Get-CimInstance Win32_LoggedOnUser |
groups |
User’s groups | whoami /groups; (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).Claims |
pinky |
Lightweight who | No direct equivalent; use Get-LocalUser |
su |
Switch user | runas /user:name cmd |
Examples:
# Current username
$env:USERNAME
# Current user with domain (like whoami)
whoami
# Check if running as administrator (like id -u == 0)
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
# List all groups current user belongs to (like groups)
whoami /groups
# Who is logged on (like who / w)
query user
Process Control
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
kill |
Send signal to process | Stop-Process (alias: kill) |
nice |
Run with modified priority | Start-Process -Priority BelowNormal |
nohup |
Run ignoring hangup | Start-Process -WindowStyle Hidden |
timeout |
Run with time limit | Start-Process + -Wait; custom job timeout |
sleep |
Pause execution | Start-Sleep -Seconds N |
stdbuf |
Modify stream buffering | No direct equivalent |
Examples:
# Kill a process by ID (like kill 1234)
Stop-Process -Id 1234
# Kill a process by name (like killall firefox)
Stop-Process -Name firefox
# Sleep for 5 seconds
Start-Sleep -Seconds 5
# Sleep for 500 milliseconds
Start-Sleep -Milliseconds 500
# Run a process at below-normal priority (like nice)
Start-Process -FilePath .\heavy-task.exe -Priority BelowNormal
# Run with a timeout (kill if it takes more than 30 seconds)
$proc = Start-Process -FilePath .\task.exe -PassThru
if (-not $proc.WaitForExit(30000)) {
$proc.Kill()
Write-Error "Process timed out"
}
Environment
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
env |
Print/set environment | Get-ChildItem Env:; $env:VAR |
printenv |
Print env variables | Get-ChildItem Env:; $env:VAR |
echo |
Print text | Write-Output (alias: echo); Write-Host |
printf |
Formatted print | "format" -f args; Write-Host |
expr |
Evaluate expressions | Direct arithmetic: (2 + 3); [math]:: |
Examples:
# Print all environment variables (like env or printenv)
Get-ChildItem Env:
# Print a specific variable (like printenv PATH)
$env:PATH
# Set an environment variable for the current session
$env:MY_VAR = "hello"
# Formatted output (like printf "Name: %s, Age: %d\n" Alice 30)
"Name: {0}, Age: {1}" -f "Alice", 30
# Arithmetic (like expr 5 + 3)
5 + 3
[math]::Pow(2, 10)
Write-Output sends objects down the pipeline. Write-Host writes directly to the console and bypasses the pipeline. Use Write-Output in scripts. Write-Host is for console-only output.
I/O Redirection & Pipes
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
tee |
Write to stdout and file | Tee-Object -FilePath file |
mkfifo |
Create named pipe | [IO.Pipes.NamedPipeServerStream] |
mknod |
Create special device file | No equivalent (device files are Linux-only) |
Examples:
# Tee output to both console and file (like tee)
Get-ChildItem | Tee-Object -FilePath .\listing.txt
# Append mode
Get-ChildItem | Tee-Object -FilePath .\log.txt -Append
Misc / Utilities
| Coreutils | Purpose | PowerShell Equivalent |
|---|---|---|
test |
Evaluate conditions | Test-Path; -eq, -lt, etc.; if () |
true |
Exit with success (0) | $true; exit 0 |
false |
Exit with failure (1) | $false; exit 1 |
yes |
Repeatedly print string | while($true){ "y" } |
factor |
Factorize integers | No built-in (write custom function) |
mktemp |
Create temp file/dir | [IO.Path]::GetTempFileName(); [IO.Path]::GetTempPath() |
sync |
Flush filesystem buffers | No direct equivalent |
chroot |
Run in alternate root | No equivalent (Windows has no chroot) |
Examples:
# Test if a file exists (like test -f file or [ -f file ])
Test-Path .\file.txt
Test-Path .\file.txt -PathType Leaf # must be a file
Test-Path .\dir\ -PathType Container # must be a directory
# Create a temp file (like mktemp)
$tmp = [IO.Path]::GetTempFileName()
# Use it...
Remove-Item $tmp # clean up
# Create a temp directory (like mktemp -d)
$tmpDir = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName())
New-Item -ItemType Directory -Path $tmpDir
Key Differences to Know
Aliases aren’t the same tools. PowerShell has aliases like cat, ls, cp, rm, mv, kill, echo, pwd, and mkdir. They map to PowerShell cmdlets and take PowerShell parameters, not Unix flags. For example, Get-ChildItem -Force would work but not ls -la.
ACL vs POSIX permissions. Windows uses Access Control Lists. The concepts of chmod’s octal permission bits and chown’s user:group ownership model don’t translate directly. Set-Acl and icacls are the tools, but the mental model is different.
SELinux commands have no Windows equivalent. chcon and runcon are Linux kernel features. There’s nothing comparable on Windows.
Checksums. Get-FileHash covers MD5, SHA1, SHA256, SHA384, and SHA512 natively. SHA224 and BLAKE2 are not built into PowerShell. You’d need a third-party .NET library.
For commands with no equivalent, the best options are:
- Write a short PowerShell script. Many of these are simple enough to implement in a few lines.
- Install GnuWin32 for native Windows ports of GNU tools
- Use Windows Subsystem for Linux (WSL) to run the real tools
- Install Git for Windows, which includes a Git Bash shell with most of these commands