Text processing
cut
Print selected fields, characters or bytes from each line, such as columns of a CSV or TSV file.
cut -f LIST [-d DELIM] [FILE...] | cut -c LIST [FILE...] | cut -b LIST [FILE...]
cut extracts parts of every line. It works in one of three modes: -f selects fields
separated by a single delimiter character (tab by default, any other with -d), -c selects
character positions and -b selects byte positions. A list can be single numbers,
ranges and open ranges: -f 1,3, -f 2-4, -f 3-.
cut is fast and simple, and that simplicity is its main limitation. The delimiter is exactly
one character, and every occurrence counts, so text aligned with several spaces produces empty
fields. Fields always come out in their original order, whatever order you list them in. When
you need to split on runs of whitespace, reorder columns or compute anything, use awk
instead; for proper CSV with quoted commas, use a CSV-aware tool.
Examples
Select columns of a CSV
cut -d , -f 2,4 data/users.csv | head -n 4
name,dept Alice Moreau,engineering Bob Okafor,sales Chen Wei,engineering
-d , makes the comma the delimiter and -f 2,4 keeps the second and fourth fields, name and department.
Tab is the default delimiter
cut -f 2 data/inventory.tsv
qty 12 3 5
Without -d, cut splits on tabs, which is exactly what a TSV file uses, so -f 2 gives the quantity column.
A range of fields to the end of the line
cut -d , -f 3- data/sales.csv | head -n 3
product,units,price widget,12,4.50 gadget,3,19.99
3- means from field 3 to the last one; -3 would mean fields 1 to 3.
Fixed character positions
cut -c 1-10 logs/app.log | sort -u
2026-03-14
-c 1-10 keeps the first ten characters of every line, which in this log is the date.
sort -u shows that all entries are from the same day.
Pick fields from a space-separated log
cut -d ' ' -f 1,7 access.log | head -n 4
192.0.2.10 / 192.0.2.10 /static/app.css 198.51.100.7 /login 198.51.100.7 /login
Splitting the access log on single spaces makes the client IP field 1 and the request path
field 7 (the quoted method "GET is field 6).
Everything except some fields
cut -d , --complement -f 3 data/users.csv | head -n 3
id,name,dept,joined 1,Alice Moreau,engineering,2021-04-12 2,Bob Okafor,sales,2019-11-03
--complement inverts the selection, dropping the email column and keeping the rest.
Change the delimiter in the output
cut -d , -f 1,3 --output-delimiter=$'\t' data/users.csv | head -n 3
id email 1 alice@example.com 2 bob@example.com
--output-delimiter joins the selected fields with a different string, here a tab, turning
CSV into TSV for the selected columns.
Fields of a system file
cut -d : -f 1,7 /etc/passwd | head -n 4
root:/bin/bash daemon:/usr/sbin/nologin bin:/usr/sbin/nologin sys:/usr/sbin/nologin
/etc/passwd is colon-separated; fields 1 and 7 are the user name and login shell.
Trap: field order cannot be changed
cut -d , -f 3,1 data/users.csv | head -n 2
id,email 1,alice@example.com
Asking for 3,1 still prints field 1 before field 3: cut always outputs fields in the
order they appear in the line. To swap columns use awk -F, -v OFS=, '{print $3, $1}'.
Trap: several spaces mean empty fields
echo 'alpha beta' | cut -d ' ' -f 2
echo 'alpha beta' | awk '{print $2}'
beta
Each of the three spaces is a delimiter, so field 2 is the empty string between the first
two, and cut prints an empty line. awk splits on runs of whitespace and prints beta.
Squeezing spaces first with tr -s ' ' also works.
Lines without the delimiter are printed whole
printf 'name,qty\n# comment line\nwidget,12\n' | cut -d , -f 2
echo ---
printf 'name,qty\n# comment line\nwidget,12\n' | cut -s -d , -f 2
qty # comment line 12 --- qty 12
A line that contains no delimiter at all is passed through unchanged, so the comment shows up
in the first output. -s suppresses such lines.
Trap: -c counts bytes in GNU cut
echo 'café' | cut -c 1-4 | od -c
0000000 c a f 303 \n 0000005
GNU cut -c currently behaves like -b and counts bytes. é is two bytes in UTF-8, so
positions 1 to 4 keep only its first byte (octal 303), an invalid fragment. Use awk with substr() or
cut only on ASCII text when positions matter.
The delimiter must be one character
cut -d ', ' -f 1 data/users.csv
cut: the delimiter must be a single character Try 'cut --help' for more information.
cut refuses multi-character delimiters. Split on , and strip spaces separately, or use awk -F ', '.
Common pitfalls
cut -d ' 'on text aligned with multiple spaces returns empty fields. Useawk '{print $2}'or squeeze first:tr -s ' ' | cut -d ' ' -f 2.cut -f 3,1does not reorder; output is always in input order. Useawkto reorder columns.Quoted CSV fields such as
"Smith, Jane"are split at the inner comma.cutknows nothing about quoting.A line without the delimiter is printed in full in
-fmode. Add-sto skip headers, comments or blank lines that lack it.Command output that looks tab-separated is often padded with spaces (
ps,df,ls -l). Check withcat -A, and preferawkfor such output.
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).
--complementand--output-delimiterare GNU-only. BSD/macOScuthas-b,-c,-f,-d,-sand-n.BSD/macOS
cut -ccounts characters in a UTF-8 locale; GNUcut -ccounts bytes like-b.
Options worth knowing
A selection, described in our own words. For the full list, see cut(1) or cut --help.
| Option | What it does |
|---|---|
-f, --fields LIST | Select these fields, for example 1,3 or 2-4 or 3-. |
-d, --delimiter CHAR | Use CHAR as the field delimiter instead of tab. |
-c, --characters LIST | Select these character positions (bytes in GNU cut). |
-b, --bytes LIST | Select these byte positions. |
-s, --only-delimited | Skip lines that contain no delimiter. |
--complement | Print everything except the selected fields, characters or bytes. |
--output-delimiter STRING | Join selected fields with STRING instead of the input delimiter. |
-z, --zero-terminated | Lines end with NUL instead of newline. |
-n | Ignored by GNU cut; on BSD, do not split multi-byte characters with -b. |
Related
awkScan text as records and fields, and run a small program on each line that matches a pattern.pasteMerge lines of files side by side, or join all lines of one file into a single line.columnFormat input into aligned columns or a table; turns CSV and whitespace data into readable output.trTranslate, squeeze or delete characters from standard input; for case changes, line endings and stripping characters.sortSort lines of text alphabetically, numerically, by version or by chosen fields; also merge and de-duplicate.