Skip to content
shellmap

xargsBuild and execute command lines from standard input across all 5 shells

Equivalents in every shell

Bashunix
find . -name '*.tmp' | xargs rm
Zshunix
find . -name '*.tmp' | xargs rm
Fishunix
find . -name '*.tmp' | xargs rm
PowerShellwindows
Get-ChildItem -Recurse -Filter *.tmp | ForEach-Object { Remove-Item $_.FullName }

Pipelines pass objects, so `ForEach-Object` (alias `%`) plays the xargs role.

cmd.exewindows
for /f "delims=" %f in ('dir /s /b *.tmp') do del "%f"

Use `%%f` inside a batch file.

Worked examples

Delete files found by `find` (safely, with NUL separator)

Bash
find . -name '*.tmp' -print0 | xargs -0 rm
PowerShell
Get-ChildItem -Recurse -Filter *.tmp | Remove-Item
cmd.exe
for /f "delims=" %f in ('dir /s /b *.tmp') do del "%f"

Run a command once per line of input

Bash
cat urls.txt | xargs -n1 curl -O
PowerShell
Get-Content urls.txt | ForEach-Object { Invoke-WebRequest -Uri $_ -OutFile (Split-Path $_ -Leaf) }

Run in parallel with 4 workers

Bash
cat urls.txt | xargs -n1 -P4 curl -O
PowerShell
Get-Content urls.txt | ForEach-Object -Parallel { Invoke-WebRequest -Uri $_ -OutFile (Split-Path $_ -Leaf) } -ThrottleLimit 4

Gotchas

  • xargs splits on whitespace by default — filenames with spaces or newlines break it. Use `find -print0 | xargs -0` or `xargs -d '\n'`.
  • PowerShell pipelines carry objects, not strings — call `.FullName`, `.Path`, etc. to get the bit you actually want.
  • xargs `-I {}` inserts each item at a placeholder; PowerShell uses `$_` inside `ForEach-Object` for the same role.
  • `ForEach-Object -Parallel` requires PowerShell 7+; Windows PowerShell 5.1 needs `Start-Job` or `Start-ThreadJob` for parallelism.

WSL & PowerShell Core notes

pwshpwsh has no `xargs` binary — `ForEach-Object` is the pipeline-loop equivalent. The big semantic difference: `xargs cmd a b c` batches inputs into ONE `cmd` invocation with many args (efficient for `rm`, `mv`); `ForEach-Object { cmd $_ }` runs `cmd` once per input (slower for high-cardinality cases). For batching in pwsh, use `Get-ChildItem ... | Remove-Item` (which natively accepts pipeline input) instead of constructing a per-item loop.
WSLWSL ships GNU xargs which supports `-d '\n'` (delimiter), `-P N` (parallel), and `-0` (NUL-separated). macOS ships BSD xargs which lacks `-d` — portable scripts targeting both should use `find ... -print0 | xargs -0` (NUL-separated, no flag dependency). Inside WSL on Windows-side files (`xargs -P 8 rm < /mnt/c/junk-list.txt`), DrvFs serializes some metadata operations, so `-P` may not give the speedup you expect.

Related glossary

Common tasks using xargs

Related commands