Skip to content
shellmap

set-contentWrite a string to a file (overwrite) — bash > redirection across all 5 shells

Equivalents in every shell

Bashunix
echo "hello" > file.txt

Shell-level redirection. `>` truncates and writes; `>>` appends. Bytes flow as-is — no formatting, no encoding conversion (the file is whatever the writing process emits).

Zshunix
echo "hello" > file.txt

Same `>` redirection as bash, plus `MULTIOS` (writes to multiple targets if you redirect twice on one line) and `>!` to override `noclobber`.

Fishunix
echo "hello" > file.txt

Same `>` redirection. Fish adds `>?` — noclobber semantics in one symbol (errors if the file exists). Bytes are written as-is.

PowerShellwindows
Set-Content -Path file.txt -Value "hello"

Writes the `.ToString()` of each input object, one per line, with NO formatting (unlike `Out-File`). `-NoNewline` to omit the trailing line break; `-Encoding utf8` to force UTF-8 (default is UTF-16 LE w/ BOM on Win PS 5.1; UTF-8 NoBOM on pwsh 7+); `-AsByteStream` (pwsh 6+) for raw binary writes.

cmd.exewindows
echo hello > file.txt

Same `>` semantics as Unix. `>>` to append. cmd `echo` does NOT strip surrounding double-quotes — `echo "hello" > x` writes `"hello"` WITH the quotes; omit the quotes for unquoted text.

Worked examples

Write a string to a file (overwrite)

Bash
echo "hello" > file.txt
PowerShell
Set-Content -Path file.txt -Value "hello"
cmd.exe
echo hello > file.txt

Round-trip a file through a transformation without re-formatting

Bash
sed 's/foo/bar/g' in.txt > out.txt
PowerShell
(Get-Content in.txt) -replace 'foo','bar' | Set-Content out.txt

Write raw bytes (binary safe)

Bash
printf "\x00\xff" > raw.bin
PowerShell
Set-Content -Path raw.bin -Value ([byte[]](0,255)) -AsByteStream

Gotchas

  • `Set-Content` writes the `.ToString()` of each input — NOT the formatted/console representation. `Get-Process | Set-Content procs.txt` writes lines like `System.Diagnostics.Process (firefox)`, NOT the table you see in the console. For console-style formatting use `Out-File`; for structured data use `Export-Csv` or `ConvertTo-Json | Set-Content`.
  • Encoding default differs by version: Windows PowerShell 5.1 writes UTF-16 LE WITH BOM; pwsh 6+ writes UTF-8 NO BOM. Scripts run on both versions produce non-byte-identical files unless you pass `-Encoding utf8NoBOM` (pwsh 7) explicitly. This breaks tooling that hashes files or diffs against canonical text.
  • `Set-Content` adds a trailing newline after the last line by default. Pass `-NoNewline` to suppress it — required when round-tripping files whose terminal-newline state matters (config files, certain git blobs, header-only HTTP captures).
  • Pipeline input is BATCHED into one file write per item: `1..10000 | Set-Content out.txt` opens, writes, and re-opens the file repeatedly — pathologically slow on large arrays. For bulk writes, materialise first: `(1..10000) -join "`n" | Set-Content out.txt`, or use `[IO.File]::WriteAllLines()` for true bulk performance.
  • On Windows, `Set-Content` honours the `ReadOnly` file attribute — it ERRORS if the target is read-only. Pass `-Force` to overwrite (which clears the attribute). Unix permissions (`chmod -w`) are honoured equivalently on pwsh 6+ Linux/macOS.

WSL & PowerShell Core notes

pwsh`Set-Content` is fully cross-platform. The big trap is encoding — Windows PowerShell 5.1 defaults to UTF-16 LE with BOM, pwsh 6+ to UTF-8 NoBOM. Always pass `-Encoding utf8NoBOM` for portability. Line endings follow the platform: Windows writes CRLF, Linux/macOS write LF unless you pre-`-replace` to normalise. `-AsByteStream` (pwsh 6+, replaces the obsolete `-Encoding Byte` from 5.1) is the cross-platform binary-safe form.
WSLFrom inside WSL bash, `>` writes an LF-newline UTF-8 file regardless of NTFS / ext4 path. Calling pwsh `Set-Content` from WSL via `pwsh.exe -c "Set-Content x.txt -Value hi"` writes a Windows-side file that may be CRLF + UTF-16 LE — the encoding mismatch is the most common breakage when scripts straddle the boundary. Pin `-Encoding utf8NoBOM` explicitly.

Related commands