CLI text-processing one-liners
Everyone knows sed
for quick find-and-replace, but it can also splice files together in memory, run shell commands, sample lines, and tee matches out to another file. Here are five surprisingly useful tricks—with copy-ready snippets and portability notes for GNU vs. BSD/macOS.
Table of Contents
1) Run shell commands inside replacements (e
flag)
Scope: GNU sed
(Linux, Homebrew gsed
on macOS). Executes the right-hand side as a shell command and substitutes its output. Powerful—handle with care.
Use-case: Fill placeholders in a template with dynamic values (date, git hash, hostname, etc.).
# template.txt:
# Build {{DATE}} • Commit {{GIT}} • Host {{HOST}}
sed -E \
-e 's/\{\{DATE\}\}/date +%F/e' \
-e 's/\{\{GIT\}\}/git rev-parse --short HEAD/e' \
-e 's/\{\{HOST\}\}/hostname/e' \
template.txt
macOS/BSD alternative (no e
flag)
# Use the shell to expand variables, then plain sed:
DATE=$(date +%F) GIT=$(git rev-parse --short HEAD) HOST=$(hostname) \
sed -E "s/\{\{DATE\}\}/$DATE/; s/\{\{GIT\}\}/$GIT/; s/\{\{HOST\}\}/$HOST/" template.txt
2) Select every nth line with step addressing
Use-case: Sample a gigantic log: print every 3rd line (or 10th, etc.).
# Every 3rd line (GNU sed):
sed -n '1~3p' big.log
# Every 10th line:
sed -n '1~10p' big.log
POSIX/BSD sed workaround
# Print 1st, 4th, 7th, ... line (no ~ support):
sed -n '1p; n; n; :a; n; n; n; p; ba' big.log
3) De-duplicate consecutive lines (no uniq
needed)
Use-case: Collapse runs of identical adjacent lines to a single line (e.g., noisy logs).
# Input:
# A
# A
# B
# B
# B
# C
sed '$!N; /^\(.*\)\n\1$/!P; D' file.txt
# Output:
# A
# B
# C
4) Write matches to a separate file with w
Use-case: Extract error messages to errors.txt
while leaving stdout clean or doing other processing.
# Capture everything after "ERROR: " into errors.txt
sed -nE 's/^ERROR:\s+(.*)$/\1/w errors.txt' server.log
5) Multi-line editing by “slurping” lines
Use-case: Join backslash-continued lines or do a substitution that crosses line breaks.
# Join lines ending with backslash "\" into a single logical line:
sed -e ':a' -e '/\\$/N; s/\\\n//; ta' source.txt
# Replace patterns that span a newline (e.g., "foo\nbar" → "foobar"):
sed ':a;N;$!ba; s/foo\nbar/foobar/g' input.txt
Quick Copy-Paste Cheat Sheet
# 1) Dynamic replacements (GNU sed):
sed -E 's/\{\{DATE\}\}/date +%F/e; s/\{\{GIT\}\}/git rev-parse --short HEAD/e' template.txt
# 2) Every n-th line (GNU sed):
sed -n '1~5p' big.log
# 3) Collapse adjacent duplicates:
sed '$!N; /^\(.*\)\n\1$/!P; D' file.txt
# 4) Write matches to a file:
sed -nE 's/^ERROR:\s+(.*)$/\1/w errors.txt' server.log
# 5) Multi-line “slurp” tricks:
sed -e ':a' -e '/\\$/N; s/\\\n//; ta' source.txt
sed ':a;N;$!ba; s/foo\nbar/foobar/g' input.txt
sed -Ef script.sed input.txt
for readability and version control.
No comments:
Post a Comment