Skip to content
shellmap

Merge multiple files into one

Concatenate the contents of several files into a single output file.

How to merge multiple files into one in each shell

Bashunix
cat file1.txt file2.txt file3.txt > combined.txt

Globs expand: `cat *.log > all.log` (alphabetical). For numeric-order: `cat $(ls -1v file*.log) > all.log` (-v = natural sort, so `file10.log` comes after `file9.log`, not after `file1.log`). To add separator between files: `awk 'FNR==1 && NR>1 {print "---"} 1' f*.log > all.log`. To DEDUPE while merging: `awk '!seen[$0]++' f*.log > all.log` (preserves first occurrence order).

Zshunix
cat file1.txt file2.txt file3.txt > combined.txt

Same external `cat`. zsh-specific glob ordering: `cat file*.log(.On) > all.log` — `(.On)` is a zsh glob qualifier — `.` regular files, `On` order by NAME descending. zsh's glob qualifiers are the cleanest way to sort by mtime / size / type without piping through `sort`/`ls`.

Fishunix
cat file1.txt file2.txt file3.txt > combined.txt

Same external `cat`. Fish glob: `cat *.log > all.log` works identically.

PowerShellwindows
Get-Content file1.txt, file2.txt, file3.txt | Set-Content combined.txt

`Get-Content` accepts COMMA-separated paths — reads each in order, streams into the pipeline. `Set-Content` writes them concatenated. For globs: `Get-Content *.log | Set-Content all.log`. Default Encoding: pwsh 5.1 writes Windows-1252 / UTF-16; pwsh 6+ writes UTF-8 without BOM. Specify explicitly: `Set-Content -Encoding utf8NoBOM all.log`. For RAW (no line-by-line splitting + faster): `Get-Content -Raw file1.txt, file2.txt | Set-Content combined.txt`.

cmd.exewindows
copy /b file1.txt+file2.txt+file3.txt combined.txt

`copy /b` BINARY mode — concatenates byte-for-byte. The `+` syntax merges into a SINGLE output file. Default cmd `copy file1+file2` is TEXT mode + stops at first Ctrl-Z (0x1A) — corrupts binary. Always use `/b` for safety. Globs: `copy /b *.log combined.log` (alphabetical order). To NOT prompt on overwrite: `copy /b /y *.log combined.log`.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • **Trailing-newline gotcha — files that don't end in `\n`**: `cat a.txt b.txt > out.txt` where `a.txt` has no trailing newline glues `a.txt`'s last line directly onto `b.txt`'s first line: `lastline-of-afirstline-of-b`. Not a bug — `cat` does byte-faithful concat. For safe text-file merging: `awk 1 a.txt b.txt > out.txt` (`awk 1` prints each line + ensures trailing newline). Or `for f in *.log; do cat "$f"; echo; done > all.log` (extra blank between files).
  • **Binary vs text mode — Windows cmd `copy`**: default `copy` (no flag) is TEXT mode on cmd — adds Ctrl-Z (0x1A) at end of each input + stops reading at first 0x1A in source. Corrupts binary files (JPGs, ISOs, .docx) silently. Always use `copy /b` for non-text. `xcopy` is BINARY by default — `xcopy /Y file1.bin combined.bin` works without flag.
  • **Memory + speed**: `cat *.log > all.log` streams (constant memory, fast). pwsh `Get-Content *.log -Raw | Set-Content all.log` reads each file FULLY into memory then writes — OOM on multi-GB logs. For huge concatenation on pwsh: `[System.IO.File]::ReadAllBytes` per source + `[System.IO.File]::WriteAllBytes` to a `FileStream` (manual streaming). Or shell out: `cmd /c "copy /b a+b+c combined"`.
  • **Encoding consistency**: merging files of mixed encodings (UTF-8, UTF-16, Windows-1252) without normalization produces gibberish. Detect with `file -i *.log` (Linux/macOS) — outputs `text/plain; charset=utf-8` per file. Normalize: `iconv -f WINDOWS-1252 -t UTF-8 latin.txt > latin.utf8.txt` before concatenating. pwsh: `Get-Content latin.txt -Encoding windows1252 | Set-Content latin.utf8.txt -Encoding utf8NoBOM`.

Related commands

Related tasks