CodingNic

Advanced Terminal Commands

Cut, Sed, Awk, and Xargs

Advanced Terminal Commands 20 min read

Cut, Sed, Awk, and Xargs

Objectives

By the end of this chapter, you should be able to:

  • Explain what cut does and when to reach for it
  • Explain what sed does and when to reach for it
  • Explain what awk does and when to reach for it
  • Explain what xargs does 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:

text
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:

bash
cut -c 1-4 languages.txt
text
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:

bash
cut -d, -f2 languages.txt
text
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:

bash
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:

bash
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.

text
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:

bash
# 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:

bash
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:

bash
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:

bash
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:

  1. Recreate languages.txt and use cut two different ways โ€” by character position and by delimiter โ€” to see them agree on this particular file.
  2. Use sed to replace a word across a text file of your own, first without -i to preview it, then with -i to actually save it.
  3. Use awk to pull a single field out of history or df -h.
  4. Use find piped into xargs to run wc -l across every file in a folder at once.

Recap

  • cut slices lines by character position (-c) or by delimiter and field (-d/-f).
  • sed finds and replaces text; add -i to edit the file in place instead of just printing the result.
  • awk prints specific fields from delimited or tabular text, using -F for the delimiter and $1, $2, etc. for fields.
  • xargs takes 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.