About cut
cut removes sections from each line of files and writes the result to standard output. It's perfect for extracting specific columns from structured text data like CSV files, logs, and delimited files.
Basic Syntax: cut OPTION... [FILE]...
Main Options:
-c- Select by character positions-f- Select by fields (columns)-d- Specify field delimiter (default is TAB)-b- Select by byte positions--complement- Invert selection (show everything except specified)--output-delimiter- Specify output delimiter
Example 1: Extract Specific Character Positions
Use -c to extract specific characters by position. Positions are numbered starting from 1.
# Sample data
echo "Hello World" > test.txt
echo "Linux Admin" >> test.txt
echo "System Tool" >> test.txt
# Extract first 5 characters
cut -c 1-5 test.txt
# Extract specific character (7th position)
cut -c 7 test.txt
# Extract from position 7 to end
cut -c 7- test.txt
# Extract up to position 5
cut -c -5 test.txt
# Extract multiple ranges
cut -c 1-3,7-9 test.txt
Output (first 5 chars):
Hello
Linux
Syste
Note:
Character positions are 1-indexed. Ranges can be combined with commas. Use "-5" for "up to 5", "7-" for "from 7 to end", and "3-7" for "from 3 to 7 inclusive".
Example 2: Extract Fields with Default Delimiter (TAB)
Use -f to extract fields. By default, cut uses TAB as the field delimiter.
# Create TAB-delimited file
printf "John\tDoe\t30\tEngineer\n" > users.txt
printf "Mary\tSmith\t25\tDoctor\n" >> users.txt
printf "Bob\tJones\t35\tTeacher\n" >> users.txt
# Extract first field (first name)
cut -f 1 users.txt
# Extract multiple fields (first and last name)
cut -f 1,2 users.txt
# Extract range of fields
cut -f 2-4 users.txt
# Extract all fields from 3rd onward
cut -f 3- users.txt
Output (fields 1,2):
John Doe
Mary Smith
Bob Jones
Note:
Without -d option, TAB is the default delimiter. Fields are numbered starting from 1. Multiple fields are output with the same delimiter used for input.
Example 3: Using Custom Delimiters
Use -d to specify a different field delimiter like comma, colon, space, or pipe.
# CSV file (comma-delimited)
cat << EOF > employees.csv
John,Doe,Engineering,75000
Mary,Smith,Sales,68000
Bob,Jones,Marketing,72000
EOF
# Extract first field from CSV
cut -d ',' -f 1 employees.csv
# Extract multiple fields
cut -d ',' -f 1,3 employees.csv
# Extract salary (last field)
cut -d ',' -f 4 employees.csv
# Process /etc/passwd (colon-delimited)
cut -d ':' -f 1,6 /etc/passwd | head -5
# Space-delimited data
echo "apple banana cherry date" | cut -d ' ' -f 2,4
# Pipe-delimited
echo "field1|field2|field3|field4" | cut -d '|' -f 2-3
Output (names and departments):
John,Engineering
Mary,Sales
Bob,Marketing
Note:
The -d option accepts only a single character as delimiter. For multi-character delimiters, use awk instead. Common delimiters: comma (,), colon (:), semicolon (;), pipe (|), space.
Example 4: Changing Output Delimiter
Use --output-delimiter to change the delimiter in the output, useful for format conversions.
# Convert CSV to TAB-delimited
cut -d ',' -f 1,2,3 employees.csv --output-delimiter=$'\t'
# Convert CSV to pipe-delimited
cut -d ',' -f 1-3 employees.csv --output-delimiter='|'
# Add custom separator
cut -d ',' -f 1,4 employees.csv --output-delimiter=' earns $'
# Convert /etc/passwd format
cut -d ':' -f 1,3,6 /etc/passwd --output-delimiter=' | ' | head -3
# Space to comma conversion
echo "apple banana cherry" | cut -d ' ' -f 1-3 --output-delimiter=','
Output (name and salary with custom delimiter):
John earns $75000
Mary earns $68000
Bob earns $72000
Note:
--output-delimiter can be a string, not just a single character. Use $'\t' for TAB in bash. This makes cut useful for simple file format conversions.
Example 5: Working with /etc/passwd
Common system administration task: extracting user information from /etc/passwd file.
# /etc/passwd format:
# username:password:UID:GID:comment:home:shell
# Extract all usernames
cut -d ':' -f 1 /etc/passwd
# Extract usernames and home directories
cut -d ':' -f 1,6 /etc/passwd
# Extract usernames and shells
cut -d ':' -f 1,7 /etc/passwd | grep -v nologin
# Get user info in readable format
cut -d ':' -f 1,3,6 /etc/passwd --output-delimiter=' (UID: ' | \
sed 's/$/) Home: /' | head -5
# Find users with UID >= 1000 (regular users)
cut -d ':' -f 1,3 /etc/passwd | awk -F: '$2 >= 1000'
# List users with bash shell
cut -d ':' -f 1,7 /etc/passwd | grep '/bash$' | cut -d ':' -f 1
Output (usernames and home dirs):
root:/root
daemon:/usr/sbin
john:/home/john
mary:/home/mary
Note:
/etc/passwd is colon-delimited with 7 fields. This is one of the most common uses of cut in system administration for user management and auditing.
Example 6: Using Complement to Exclude Fields
Use --complement to invert selection and show everything except the specified fields.
# Sample data
cat << EOF > data.txt
ID,Name,Age,Email,Phone,Address
1,John,30,john@email.com,555-1234,123 Main St
2,Mary,25,mary@email.com,555-5678,456 Oak Ave
EOF
# Show everything except email (field 4)
cut -d ',' -f 4 --complement data.txt
# Exclude multiple fields (email and phone)
cut -d ',' -f 4,5 --complement data.txt
# Keep only first 3 characters of each line
cut -c 1-3 data.txt
# Show everything except first 3 characters
cut -c 1-3 --complement data.txt
# Remove sensitive data columns
cut -d ',' -f 4,5,6 --complement data.txt
Output (without email):
ID,Name,Age,Phone,Address
1,John,30,555-1234,123 Main St
2,Mary,25,555-5678,456 Oak Ave
Note:
--complement is useful for removing columns from data sets. Perfect for sanitizing data by removing sensitive fields or simplifying output.
Example 7: Processing Command Output with Pipes
Cut is commonly used in pipelines to extract specific fields from command output.
# Extract usernames from ps output
ps aux | tail -n +2 | cut -c 1-8 | sort -u
# Get process IDs from ps
ps aux | tail -n +2 | tr -s ' ' | cut -d ' ' -f 2
# Extract IP addresses from netstat
netstat -tn | tail -n +3 | tr -s ' ' | cut -d ' ' -f 5 | \
cut -d ':' -f 1 | sort -u
# Get mounted filesystem names
df -h | tail -n +2 | tr -s ' ' | cut -d ' ' -f 1
# Extract file permissions from ls -l
ls -l | tail -n +2 | cut -c 1-10
# Get date from date command
date | cut -d ' ' -f 2-4
# Extract email domains
cut -d '@' -f 2 emails.txt | sort -u
Output (unique users from ps):
daemon
john
root
www-data
Note:
Use tail -n +2 to skip header lines. Use tr -s ' ' to squeeze multiple spaces into one before cutting. Combine with sort -u for unique values.
Example 8: Extract Columns from Log Files
Use cut to parse and extract relevant information from various log file formats.
# Apache/Nginx access log example:
# 192.168.1.1 - - [12/Nov/2025:10:30:45] "GET /index.html" 200 1234
# Extract IP addresses
cut -d ' ' -f 1 access.log
# Extract HTTP status codes
cut -d ' ' -f 9 access.log | sort | uniq -c
# Syslog format: timestamp hostname process[pid]: message
# Extract only timestamps
cut -d ' ' -f 1-3 /var/log/syslog
# Extract process names from syslog
cut -d ' ' -f 5 /var/log/syslog | cut -d ':' -f 1 | sort | uniq -c
# CSV log file - extract timestamp and error level
cut -d ',' -f 1,3 application.log
# Extract failed login IPs from auth.log
grep "Failed password" /var/log/auth.log | \
grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | sort | uniq -c | sort -rn
Output (IP addresses from access log):
192.168.1.1
192.168.1.15
10.0.0.50
192.168.1.1
203.0.113.42
Note:
Log file parsing often requires combining cut with other tools like grep, awk, and sort. For complex parsing, awk may be more suitable than cut.
Example 9: Working with Fixed-Width Data
Extract data from fixed-width format files using character positions.
# Fixed-width data (common in legacy systems)
cat << EOF > fixed_width.txt
JohnDoe 30EngineerNew York
MarySmith 25Doctor Boston
BobJones 35Teacher Chicago
EOF
# Extract name (positions 1-13)
cut -c 1-13 fixed_width.txt
# Extract age (positions 14-15)
cut -c 14-15 fixed_width.txt
# Extract occupation (positions 16-25)
cut -c 16-25 fixed_width.txt
# Extract city (positions 26-)
cut -c 26- fixed_width.txt
# Extract multiple sections
cut -c 1-13,16-25 fixed_width.txt
# Create formatted output
paste <(cut -c 1-13 fixed_width.txt) \
<(cut -c 14-15 fixed_width.txt) \
<(cut -c 16-25 fixed_width.txt) \
--delimiter=','
Output (names):
JohnDoe
MarySmith
BobJones
Note:
Fixed-width formats are common in mainframe data and legacy systems. Character position extraction is more reliable than field-based extraction for this format.
Example 10: Practical Data Processing Scenarios
Real-world examples combining cut with other commands for data processing tasks.
# Extract and count unique email domains
cut -d '@' -f 2 email_list.txt | sort | uniq -c | sort -rn
# Create a summary report from CSV
echo "Department,Average Salary"
cut -d ',' -f 3,4 employees.csv | tail -n +2 | \
awk -F, '{dept[$1]+=$2; count[$1]++} \
END {for(d in dept) print d","dept[d]/count[d]}'
# Generate username list from full names
cut -d ',' -f 1,2 people.csv | \
awk -F, '{print tolower($1 substr($2,1,1))}'
# Extract phone area codes
cut -d '-' -f 1 phone_numbers.txt | sort | uniq -c
# Create a backup of sensitive data with some fields masked
cut -d ',' -f 1,2,3 --complement customers.csv > customers_public.csv
# Monitor specific log fields in real-time
tail -f /var/log/application.log | cut -d '|' -f 2,4
# Extract and format date components
date '+%Y-%m-%d' | (IFS='-' read y m d; echo "Year: $y Month: $m Day: $d")
# Convert between file formats
cut -d ',' -f 1-5 input.csv --output-delimiter=$'\t' > output.tsv
Output (email domain counts):
45 gmail.com
23 yahoo.com
18 company.com
12 hotmail.com
Note:
Cut excels in pipelines. For complex field manipulations, consider awk. For record-based processing, consider sed or perl.
Additional Tips & Best Practices
- Single-character delimiter: Cut only supports single-character delimiters. For multi-character delimiters, use awk or sed
- Lines without delimiters: By default, cut prints lines without delimiters unchanged. Use -s to suppress these lines
- Performance: Cut is very fast and efficient for simple column extraction. For complex parsing, awk may be more appropriate
- Tab characters: In bash, use $'\t' to represent TAB:
cut -d $'\t' -f 1 file - Multiple ranges: Combine ranges with commas:
cut -c 1-3,7-9,15-20 - Byte vs character: Use -c for characters (multi-byte aware) and -b for bytes. For ASCII data, they're identical
- Combination with paste: Use paste to reassemble cut fields:
paste <(cut -f1 file) <(cut -f3 file) - CSV with quotes: Cut doesn't handle quoted fields in CSV. Use csvcut from csvkit or awk for proper CSV parsing
- Empty fields: Cut preserves empty fields in delimited data
- Last field: Cut can't easily extract the "last field". Use awk for that:
awk -F: '{print $NF}' - Debugging: Use head/tail to test on small samples before processing large files
- Alternative tools: For complex parsing: awk (field processing), sed (pattern-based), csvkit (CSV), jq (JSON)