Skip to content

Writing find, awk and sed One-Liners with AI (and Verifying Them)

Get correct one-liners from a model on the first or second try β€” how to describe the task, the GNU vs BSD trap, and a verification loop that catches wrong answers safely.

●By 12 min read

This is the task local models are best at in day-to-day administration. find, awk, and sed have enormous, rarely-used surfaces β€” most people know 10% of each and re-learn the rest every few months. Describing what you want in a sentence and getting working syntax back is a genuine productivity gain.

It is also low risk, provided you verify before acting. These commands operate in bulk, so a wrong answer is wrong across ten thousand files at once.

Describe the Task, Not the Command

The quality of the answer tracks the quality of the description almost perfectly. Include four things:

1. Sample input β€” two or three real lines. This resolves more ambiguity than any amount of prose about the format.

2. Desired output β€” exactly what you want back, for those same lines.

3. Platform β€” "GNU coreutils on Debian" or "BSD userland on macOS". This is the single most common cause of wrong answers.

4. Constraints β€” filenames may contain spaces, must not recurse into mounts, must not modify files in place.

$ ollama run llama3.2 "Write a shell one-liner.

PLATFORM: GNU coreutils on Debian 12, bash.

INPUT β€” lines from an nginx access log:

203.0.113.5 - - [22/Aug/2026:11:02:14 +0000] \"GET /api/v1/users HTTP/1.1\" 200 1234

198.51.100.9 - - [22/Aug/2026:11:02:15 +0000] \"POST /api/v1/login HTTP/1.1\" 503 88

WANT: the 10 request paths that returned 5xx most often, as 'count path'.

CONSTRAINTS: read-only, no temp files, must handle quoted paths.

Give the command, then explain each part. If a flag is GNU-only, say so."

Compare that with "how do I find 5xx errors in nginx logs" β€” which gets you a generic grep and a follow-up round trip. Two extra lines of input saves two exchanges.

The GNU vs BSD Trap

Models default to GNU behaviour because that is what most documentation targets. On macOS, BSD, Alpine, or a busybox container the same command silently behaves differently β€” or errors:

TaskGNUBSD / macOS
In-place editsed -i 's/a/b/' fsed -i '' 's/a/b/' f
Extended regexsed -E or -rsed -E only
Date arithmeticdate -d '-7 days'date -v-7d
find newer than-newermt '-7 days'-newerBt or -mtime
Sort by versionsort -VOften unavailable
Read null-delimitedxargs -0xargs -0 β€” supported on both

The BSD sed -i gotcha β€” on macOS, sed -i 's/a/b/' treats s/a/b/ as the backup suffix and then fails confusingly. It needs an explicit empty argument.

Always state your platform β€” and check with --version when the answer does something unexpected. Busybox in containers is a frequent surprise.

The Verification Loop

Never run a generated bulk command against real data on the first pass. This sequence takes under a minute and catches essentially every bad answer:

# 1. See what it MATCHES before it acts

$ find /var/log -type f -mtime +30 -print # not -delete

# 2. Print the transformation instead of applying it

$ sed -E 's/old/new/g' config.conf | head -20 # not -i

# 3. Test awk on a sample, not the whole file

$ head -100 access.log | awk '{print $9, $7}'

# 4. Count first β€” does the number look plausible?

$ find /data -name '*.tmp' | wc -l

# 5. Run against a copy for anything destructive

$ cp -r /data/sample /tmp/verify && cd /tmp/verify && <command>

# 6. Only then, on the real target

$ find /var/log -type f -mtime +30 -delete

Step 4 is the underrated one β€” if you expected a few dozen files and the count is 40,000, the command is wrong. A magnitude check catches errors that reading the command does not.

Prefer -print over -delete permanently β€” write the find as a listing, review it, then re-run with the action. The two-step habit costs seconds.

Use our regex tester β€” paste the pattern into the regex tester with sample lines before trusting it in sed or grep.

sponsored

Mistakes Models Repeat

find -exec quoting β€” -exec sh -c 'cmd $0' {} \; variants get mangled often. Prefer -exec cmd {} + where possible, or pipe -print0 into xargs -0.

Assuming whitespace-free filenames β€” a generated loop like for f in $(find ...) breaks on spaces. Insist on -print0 and while IFS= read -r -d ''.

Greedy regex β€” .* matching further than intended is the most common sed error. Test against a line with two occurrences of the delimiter.

Wrong awk field after a format change β€” $9 in a log line is only correct until someone adds a field. Prefer matching on content over position where you can.

Ignoring filesystem boundaries β€” a find / without -xdev walks into network mounts and container filesystems, which is slow and occasionally destructive.

Locale-dependent sorting β€” results differ between LC_ALL=C and a UTF-8 locale. For deterministic output, set it explicitly.

Combining -delete with -depth wrongly β€” find has ordering subtleties when deleting directories. Verify with -print and consider -depth explicitly.

Patterns Worth Knowing Yourself

Ask for these once, then keep them. Knowing the safe shapes means you can spot when a generated answer deviates:

# Null-safe iteration over found files

$ find /data -type f -name '*.log' -print0 \

| while IFS= read -r -d '' f; do printf 'processing %s\n' "$f"; done

# Batch exec, one process for many files (fast and quoting-safe)

$ find /data -type f -name '*.tmp' -exec rm -v {} +

# Bounded search: stay on one filesystem, limit depth

$ find /var -xdev -maxdepth 3 -type d -name cache

# awk aggregation with a formatted report

$ awk '$9 ~ /^5/ {n[$7]++} END {for (p in n) printf "%6d %s\n", n[p], p}' access.log \

| sort -rn | head

# sed with a backup, so the first run is recoverable

$ sed -i.bak -E 's/^(listen )80;/\18080;/' /etc/nginx/sites-enabled/site

# Field extraction that does not depend on position

$ awk -F'"' '{print $2}' access.log | awk '{print $2}' | sort | uniq -c | sort -rn

-exec ... + over ; β€” the plus form batches arguments into far fewer process invocations. On large trees the difference is dramatic.

sed -i.bak on first run β€” GNU sed writes a backup with that suffix. Cheap insurance you can delete once verified.

When to Stop Using a One-Liner

If the generated command exceeds roughly two lines, contains nested quoting three levels deep, or needs a comment to be readable, it should be a script instead. A one-liner nobody can review is a liability regardless of who wrote it.

At that point, move to a proper script with set -euo pipefail, run it through ShellCheck, and apply the review process in our AI script review guide. Our shell script generator gives you a safe skeleton to paste the logic into.

Frequently Asked Questions

Are AI-generated find and sed commands reliable?

They are reliable enough to be a real time-saver, and unreliable enough that you must verify. The most common failures are assuming GNU behaviour, mishandling filenames with spaces, and greedy regex. Always list matches with -print or pipe sed to stdout before acting.

Why does sed -i fail on macOS but work on Linux?

BSD sed requires an explicit backup-suffix argument, so it must be sed -i '' 's/a/b/' file. GNU sed treats the suffix as optional. Telling the model your platform up front avoids this and a dozen similar differences in date, find, and sort.

How do I safely test a bulk command before running it?

Replace the action with a listing β€” find -print instead of -delete, sed to stdout instead of -i β€” then count the matches and check whether the magnitude is plausible. For destructive operations, run against a copy in /tmp first.

What is the best way to handle filenames with spaces?

Use find -print0 piped into either xargs -0 or a while IFS= read -r -d '' loop, and quote every expansion. Reject any generated command that iterates over $(find ...) or parses ls output β€” both break on whitespace.

When should a one-liner become a script instead?

When it exceeds about two lines, nests quoting more than two levels, or needs explanation to be readable. At that point put it in a script with set -euo pipefail, run ShellCheck, and review it properly β€” an unreviewable one-liner is a risk whoever wrote it.

sponsored

Related Tools

See also