Text processing
paste
Merge lines of files side by side, or join all lines of one file into a single line.
paste [OPTION...] [FILE...]
paste reads several files in parallel and writes line 1 of each, joined by tabs, then line 2
of each, and so on: it glues files together as columns. It is the horizontal counterpart of
cat, and the opposite of cut.
With -s (serial) it works on one file at a time and joins all of its lines into one line. That
makes paste -sd, the standard idiom for turning a list into a comma-separated string, and
paste -sd+ | bc a quick way to add up a column of numbers. Using - as a file name several
times reads that many lines of standard input per output line, which reshapes a list into rows.
Examples
Put two files next to each other
paste data/hosts.txt data/numbers.txt | head -n 4
web01 10.0.0.11 42 web02 10.0.0.12 7 db01 10.0.0.21 19 cache01 10.0.0.31 3
Line N of each file ends up on line N of the output, separated by a tab.
Files of different lengths
paste todo.txt data/numbers.txt
buy milk 42 fix login bug 7 write tests 19 fix logout bug 3 deploy v2.4 100 7 58 21 3 64
todo.txt runs out after 5 lines; paste keeps going and leaves its column empty, so the
remaining lines start with a tab.
Choose the separator
paste -d , todo.txt data/fruits.txt | head -n 3
buy milk,banana fix login bug,apple write tests,cherry
-d , joins the columns with a comma instead of a tab.
Join all lines into one, comma-separated
paste -s -d , todo.txt
buy milk,fix login bug,write tests,fix logout bug,deploy v2.4
-s pastes the lines of one file serially into a single line; with -d , they are separated by commas.
Build a space-separated list from a column
cut -d ' ' -f 1 data/hosts.txt | paste -s -d ' '
web01 web02 db01 cache01
The first field of every line, collected into one line, ready to paste into a command or a config value.
Add up a column of numbers
paste -s -d + data/numbers.txt | bc
324
paste builds the expression 42+7+19+...+64 and bc evaluates it: the numbers add up
to 324.
Turn a list into rows of two
paste - - < data/fruits.txt
banana apple cherry apple date banana apple elderberry cherry fig
Each - reads the next line from standard input, so two dashes consume two lines per output
row. The 10 fruits become 5 rows of 2.
Rows of three with a custom separator
paste -d ' ' - - - < todo.txt
buy milk fix login bug write tests fix logout bug deploy v2.4
Three dashes give three items per row. The 5 lines don't divide evenly, so the last row has only two items followed by the separator.
Several delimiters are used in turn
paste -d ':\n' - - - < data/numbers.txt
42:7 19 3:100 7 58:21 3 64:
With more than one character in -d, paste cycles through them: : after the first
column, a newline after the second. The result pairs numbers as a:b with every third
number on its own line. The input runs out after 64, which leaves the last row as 64:.
Combine columns from different commands
paste -d , <(cut -d , -f 4 data/users.csv) <(cut -d , -f 2 data/users.csv) | head -n 4
dept,name engineering,Alice Moreau sales,Bob Okafor engineering,Chen Wei
Process substitution lets each column come from its own command. Here the department column
is put before the name column, a reordering that cut alone cannot do.
Interleave lines of two files
paste -d '\n' todo.txt data/poem.txt | head -n 6
buy milk The quick brown fox fix login bug jumps over the lazy dog. write tests The dog sleeps;
With a newline as the delimiter, the files' lines alternate: one from todo.txt, one from poem.txt, and so on.
Common pitfalls
pastematches lines by position only, not by a key. If the files are not in the same order, rows get mismatched silently; usejointo match on a key.In
-d, a backslash sequence like\nor\tis interpreted bypasteitself, and\0means no delimiter, not a NUL byte.A file with CRLF line endings carries its
\rinto the middle of the pasted line, which makes the terminal jump back to column 0. Strip withtr -d '\r'first.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
BSD/macOS
pasterequires a file operand: usepaste -s -d , -(with the dash) when reading standard input there; GNU accepts both forms.
Options worth knowing
A selection, described in our own words. For the full list, see paste(1) or paste --help.
| Option | What it does |
|---|---|
-d, --delimiters LIST | Use the characters in LIST as separators, cycling through them. |
-s, --serial | Paste the lines of each file into one line instead of in parallel. |
-z, --zero-terminated | Lines end with NUL instead of newline. |
Related
cutPrint selected fields, characters or bytes from each line, such as columns of a CSV or TSV file.joinJoin lines of two sorted files that share a key field, like a database join on text files.columnFormat input into aligned columns or a table; turns CSV and whitespace data into readable output.catConcatenate files and print them to standard output; also the quickest way to see a short file.bcAn arbitrary-precision calculator language, used from scripts for decimal math the shell cannot do.- Process substitutionUse <(cmd) and >(cmd) to hand a command's output to a program that wants a file name, keep while-read loops in the current shell, and avoid its timing traps.