How to Use cut paste and column Together for Quick Tables
Combine cut, paste and column to build and align tables from text: select fields, merge files side by side, pretty print columns and handle delimiters.

Three small utilities cover a lot of quick table work without writing a program: one picks columns, one glues files together and one makes the result readable. They are older than most of the tools that replace them and still the fastest for a quick look at data. They extend cut and paste and join, and the examples assume GNU coreutils 9.x and util-linux 2.40.
Pick columns with cut
cut -d: -f1,7 /etc/passwd | head -3
cut -d, -f2-4 data.csv
cut -c1-8 access.log | head -2
echo "a b c" | cut -d' ' -f1,3root:/bin/bash
daemon:/usr/sbin/nologin
bin:/usr/sbin/nologin
a b
The last example shows the main limitation: three spaces count as three delimiters, so field 3 is empty and the output is not a c. Squeeze runs of spaces first with tr -s ' ', or use awk, which splits on any whitespace by default. --complement prints all but the selected fields, and --output-delimiter=' | ' changes the separator.
Join with paste
printf '%s\n' alice bob carol > names.txt
printf '%s\n' 30 25 41 > ages.txt
paste names.txt ages.txt
paste -d, names.txt ages.txt
paste -sd, names.txtalice 30
bob 25
carol 41
alice,30
bob,25
carol,41
alice,bob,carol
paste pairs line N of each file. If the files differ in length, the shorter one is padded with empty fields, so check line counts with wc -l first. With -s it serialises one file into a single line, which is the neatest way to turn a list into a comma-separated string. Use -d',' with several characters to cycle through different separators.
Align with column
paste -d, names.txt ages.txt | column -t -s, -N NAME,AGE
mount | column -t | head -3NAME AGE
alice 30
bob 25
carol 41
column -t works out the width of each column and pads so that they line up. -s sets the input separator and -N names headers (a util-linux feature, not in the BSD version). By default it treats runs of whitespace as one separator, and empty fields get collapsed unless you pass -n in some versions, which is why a table with blank cells may shift left.
A worked pipeline
ps -eo user,pid,%mem,comm --sort=-%mem | head -6 | tr -s ' ' | cut -d' ' -f2,4,5 | column -tThe output of ps is padded with variable spaces, so tr -s squeezes them before cut. Selecting fields from space-padded output is fragile; ask the source for a delimiter when it can provide one, such as ps -o ... --no-headers and then use awk. Counting values afterwards is the subject of top values with sort and uniq.
cut and its limits
The cut command selects columns by position or by delimiter. With -d and -f, it extracts fields, and with -c it extracts character ranges. It has two limits that explain most workarounds. It uses a single-character delimiter, so a run of spaces counts as many empty fields, and it cannot reorder columns: -f3,1 prints field 1 first, because the selection is a set, not a list. When whitespace-aligned output is the input, as with ps or df, convert the runs of spaces to one with tr -s ' ' first, or use awk, which splits on any whitespace by default and can reorder freely.
Use the --output-delimiter option in GNU cut to change the separator in the output, and --complement to select everything except the named fields. Neither exists on BSD systems, where a pipeline with other tools is needed.
paste for merging side by side
Where cat joins files end to end, paste joins them line by line, placing corresponding lines side by side separated by a tab. The -d option sets other delimiters, and with several characters it cycles through them. The -s option turns each file into a single line, which is a quick way to join a list into a comma separated string: paste -sd, file. Combining it with process substitution allows merging command outputs: paste <(cut -f1 a) <(cut -f2 b) builds a table from two sources. If the inputs have different lengths, the shorter one is padded with empty fields, so check line counts first when alignment matters.
Because it works positionally, paste assumes the files are in the same order. If they are not, use join, which matches on a key, after sorting both inputs on that key.
column for presentation
The column -t command aligns whitespace-separated input into neat columns, and -s sets the input separator, as in column -s, -t file.csv. It is a display tool: it reads everything before printing, handles only simple separators and does not understand quoted fields, so a comma inside quotes splits the field. For human reading of tabular output in a terminal it is excellent. For data that another program will parse, avoid it, since the padding spaces change the content. The util-linux version also offers -J for JSON output and -N to name columns, but those options are missing on other systems.
On very wide tables, pipe the result to less -S so lines scroll horizontally instead of wrapping, which keeps columns aligned.
Building a reliable pipeline
The three tools handle clean, simple text. Check that assumption before building on it. Look for embedded delimiters, quoted fields, header lines, trailing blank lines and inconsistent column counts. A quick check with awk -F, '{print NF}' file | sort | uniq -c shows whether every row has the same number of fields. For real CSV with quotes, use a proper tool such as a CSV-aware utility or a language library, and keep cut and paste for logs and simple exports. Set LC_ALL=C for speed and predictable behaviour when the data is plain ASCII, and set a UTF-8 locale when character ranges matter. Finally, keep a sample input and the expected output beside the pipeline in the repository. A three-line test file lets the next person change a step with confidence, and it documents the format the pipeline expects.
For repeatable work, wrap the pipeline in a shell function with a name that says what it produces, and give it a header comment listing the input format. Run it against a golden sample in a test. That small amount of structure turns a one-off command that works on your machine into a tool the team can reuse. When the data stops fitting the model, because fields now contain delimiters or the format gains optional columns, the wrapper is also the single place to replace with a stronger parser.
Where this does not apply
Quoted CSV, fields with embedded delimiters and anything with a header you need to select by name call for awk or a CSV tool such as csvcut. Multi-byte characters work with cut -c only in recent GNU versions under a UTF-8 locale, while older ones count bytes. BSD column lacks -N and -s behaves slightly differently. See the GNU cut manual and the column manual page.


