Cut, Sed, Awk, and Xargs
Objectives
By the end of this chapter, you should be able to:
- Explain what
cutdoes and when to reach for it - Explain what
seddoes and when to reach for it - Explain what
awkdoes and when to reach for it - Explain what
xargsdoes and when to reach for it
๐ก Why this matters: Every command in this lesson exists to reshape or process text without opening an editor โ slicing columns out of a file, replacing text across thousands of lines, or running one command across a whole batch of files. This is what “power user” actually looks like in Terminal.
cut
cut pulls specific pieces out of each line of text. Given a file languages.txt:
Java,James
Ruby,Matz
Lisp,John
Bash,Brian
Self,David
You can cut by character position โ the -c flag grabs a range of characters from each line:
cut -c 1-4 languages.txt
Java
Ruby
Lisp
Bash
Self
That works here, but only because every language name happens to be four characters. A more reliable approach splits on a delimiter instead โ -d sets the delimiter, -f picks which field to keep:
cut -d, -f2 languages.txt
James
Matz
John
Brian
David
-f1 would give you the first field (the language names) instead. Delimiter-based cutting works regardless of how long each piece is, which position-based cutting can’t guarantee.
cut also chains naturally with what you already know:
cut -d, -f2 languages.txt | sort | head -n 2
That pulls out just the names, sorts them, and keeps the first two.
sed
sed (Stream EDitor) is a much deeper tool than this lesson can fully cover, but its most common use is find-and-replace. To swap every comma in languages.txt for a colon:
sed 's/,/:/g' languages.txt
Breaking that down: s means substitute, , is what to find, : is what to replace it with, and g means do it for every match on the line, not just the first.
Java:James
Ruby:Matz
Lisp:John
Bash:Brian
Self:David
Run cat languages.txt afterward and the file is unchanged โ by default, sed only prints the result, it doesn’t edit the file. To edit in place, add -i, but the exact syntax depends on your system:
# macOS (BSD sed) โ needs an explicit backup suffix, even if empty
sed -i '' 's/,/:/g' languages.txt
# Linux (GNU sed) โ -i works on its own
sed -i 's/,/:/g' languages.txt
cat languages.txt now shows the replacement actually saved. This is genuinely just the surface of sed โ keep pushing on it as you run into real find-and-replace problems.
awk
awk is powerful enough to be considered its own small language for text processing. The simplest form just prints a file: awk '{print}' languages.txt. Where it gets useful is printing specific fields. With -F setting the delimiter, $1 refers to the first field:
awk -F ':' '{print $1}' languages.txt
awk’s default delimiter is whitespace, so no -F is needed for space-separated input. Try it on your command history:
history | awk '{print $2}'
That prints just the command name from each history entry, dropping the line number and everything else.
awk also handles row-and-column data. Run df -h (short for “disk free, human-readable”) on its own first to see the raw table, then pull one specific value out of it:
df -h | awk 'FNR == 2 {print $4}'
FNR is the current line number โ this grabs the 4th column of the 2nd row, which is typically your available disk space.
xargs
xargs takes a list of inputs โ usually piped in from find or ls โ and runs a command once for each one. That turns a single-file command into a batch operation:
| Command | Does |
|---|---|
find . -name "*.html" | xargs grep "hello" |
Searches every .html file in the current folder for the text hello |
ls | xargs wc -l |
Counts the lines in every file in the folder |
find . -name "*.css" | xargs open |
Opens every CSS file in the current folder |
find . -name "*.html" | xargs rm |
Deletes every file ending in .html โ use with real caution |
ls | xargs -t -I {} mv {} {}.md |
Adds a .md extension to every file (-I sets a placeholder for each input; -t prints each command before running it) |
Try It
All four commands process real files, so try these yourself:
- Recreate
languages.txtand usecuttwo different ways โ by character position and by delimiter โ to see them agree on this particular file. - Use
sedto replace a word across a text file of your own, first without-ito preview it, then with-ito actually save it. - Use
awkto pull a single field out ofhistoryordf -h. - Use
findpiped intoxargsto runwc -lacross every file in a folder at once.
Recap
cutslices lines by character position (-c) or by delimiter and field (-d/-f).sedfinds and replaces text; add-ito edit the file in place instead of just printing the result.awkprints specific fields from delimited or tabular text, using-Ffor the delimiter and$1,$2, etc. for fields.xargstakes a list of inputs and runs a command once per input, turning single-file commands into batch operations.
Next lesson: writing your own shell scripts, and editing files directly in the terminal with Vim.