add-content — Append a string to a file — bash >> redirection across all 5 shells
Equivalents in every shell
echo "hello" >> file.txtShell-level append redirection. Creates the file if missing, appends if it exists. `tee -a` is the alternative when you also want the output on stdout. Kernel-level appends are atomic for writes ≤ PIPE_BUF (4KB on Linux).
echo "hello" >> file.txtSame `>>` semantics. Zsh `>>!` overrides `noclobber`. `MULTIOS` allows `echo hi >>file1 >>file2` to append to BOTH at once.
echo "hello" >> file.txtSame `>>` semantics. Fish has no analog to `tee -a` natively — use the external `tee` binary: `echo hi | tee -a file.txt`.
Add-Content -Path file.txt -Value "hello"Appends the `.ToString()` of each input to the file. Creates the file if missing. `-NoNewline` omits the trailing newline; `-Encoding utf8` forces UTF-8 (otherwise inherits the same Win PS 5.1 vs pwsh 6+ defaults as `Set-Content`).
echo hello >> file.txtSame `>>` semantics as Unix. `echo.` (with period, no space) prints an EMPTY line — useful for blank-line separators between appends. cmd `echo` does NOT strip quotes.
Worked examples
Append a timestamped line to a log file
echo "$(date) - started" >> app.logAdd-Content -Path app.log -Value "$(Get-Date) - started"echo %DATE% %TIME% - started >> app.logAppend the contents of one file to another
cat extra.txt >> main.txtGet-Content extra.txt | Add-Content main.txttype extra.txt >> main.txtAppend without a trailing newline (continue a partial line)
printf "%s" "tail" >> file.txtAdd-Content -Path file.txt -Value "tail" -NoNewlineGotchas
- Like `Set-Content`, `Add-Content` writes `.ToString()` of each input — NOT the formatted console representation. `Get-Process | Add-Content procs.log` produces `System.Diagnostics.Process (firefox)` lines, not the formatted table you'd see in the console. For formatted appends, use `Out-File -Append`; for structured appends, use `Export-Csv -Append` (pwsh 5+).
- Each `Add-Content` invocation OPENS and CLOSES the target file — for high-frequency appending inside a tight loop, this is dramatically slower than holding a handle. Bulk-friendly alternative: `$sw = [IO.File]::AppendText('app.log'); $sw.WriteLine('hi'); $sw.Close()` keeps the handle open across writes.
- Append is NOT atomic across multi-line writes — concurrent `Add-Content` calls from two processes can INTERLEAVE lines mid-record. For lock-safe logging, use a `Mutex` plus `[IO.File]::AppendAllLines()`, or route through a dedicated logger (Serilog, NLog, `Microsoft.Extensions.Logging`).
- On Windows PowerShell 5.1, appending to an existing UTF-8 file with default `-Encoding` will switch the new portion to UTF-16 LE, producing a file with TWO encodings and a BOM in the middle — unreadable by most consumers. ALWAYS pass `-Encoding` matching the file's existing encoding.
- `-Value` accepts an array — `Add-Content file.txt -Value 'a','b','c'` appends each as its own line. To append a single multi-line block as ONE record, join first: `Add-Content file.txt -Value ("a`nb`nc")`. The distinction matters when downstream tools `Get-Content` and expect per-record alignment.