- Posted on
- • Artificial Intelligence
Artificial Intelligence Automation Case Studies
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Automating Real Work with AI: 3 Bash-Friendly Case Studies for Linux
If you’re a Linux user who lives in Bash, you’ve probably felt the grind: sifting through noisy logs, turning recordings into notes, or keying data from invoices. AI can cut this toil dramatically—without abandoning your command line or bolting on heavyweight platforms. In this article, you’ll see three practical case studies you can run with standard Linux tools and a few well-placed API calls.
What you get:
Clear value: less repetitive work, faster insight, and more consistent outputs
Why it works: combine Unix philosophy (small tools, well-joined) with AI
3 real-world automations with scripts you can adapt
Installation instructions for apt, dnf, and zypper where needed
A short checklist to ship these safely
Note: The examples use local preprocessing (awk/sed/ffmpeg/tesseract) and, where helpful, an LLM via HTTP. You control what leaves your machine.
Why this is worth your time
AI thrives on pattern-heavy text. Logs, tickets, transcripts, and invoices are perfect candidates.
Linux already excels at transforming text and scheduling work. Bash is ideal “glue.”
The fastest ROI comes from summaries, classifications, and extraction—lightweight AI tasks that remove manual triage and error-prone retyping.
Privacy and cost control are possible: do the heavy lifting locally (filtering, OCR, chunking), then only send strictly necessary snippets to an LLM.
Common prerequisites
Install what we’ll use across the examples:
curl and jq for HTTP + JSON
Python and pip for optional CLI tools
ffmpeg (for audio)
tesseract-ocr and poppler-utils (for OCR/PDF)
cron or systemd timers for scheduling
Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y curl jq python3 python3-pip ffmpeg tesseract-ocr poppler-utils cron
Fedora/RHEL/CentOS (dnf):
sudo dnf install -y curl jq python3 python3-pip ffmpeg tesseract poppler-utils cronie
openSUSE (zypper):
sudo zypper install -y curl jq python3 python3-pip ffmpeg tesseract poppler-tools cron
Notes:
On RHEL-like systems, tesseract may require EPEL.
If you prefer systemd timers, cron/cronie is optional.
Environment variables for LLM API usage (example: OpenAI; set once in your shell profile):
export OPENAI_API_KEY="sk-REPLACE_ME"
export OPENAI_MODEL="gpt-4o-mini"
Case Study 1: Overnight Log Triage and a 5‑Minute Brief
Problem: On-call engineers spend hours scanning logs after incidents. We want an automatic daily brief that highlights top errors, new patterns, and suggested next steps.
What this does:
Collects yesterday’s high-signal logs (journalctl + Nginx example)
Pre-aggregates locally (privacy + lower cost)
Sends a compact sample to an LLM for a short, actionable summary
Optionally posts to Slack or writes a Markdown report
Install (tools used: jq, curl, cron/systemd):
- Already covered in prerequisites.
Script: log-brief.sh
#!/usr/bin/env bash
set -euo pipefail
: "${OPENAI_API_KEY:?Set OPENAI_API_KEY}"
MODEL="${OPENAI_MODEL:-gpt-4o-mini}"
WORKDIR="${WORKDIR:-/var/tmp/log-brief}"
mkdir -p "$WORKDIR"
YDATE="$(date -u -d 'yesterday' +%F)"
REPORT="$WORKDIR/daily-brief-$YDATE.md"
collect_logs() {
LOGBUF="$WORKDIR/raw-$YDATE.txt"
: > "$LOGBUF"
# System errors from yesterday
if command -v journalctl >/dev/null 2>&1; then
journalctl -p err -S yesterday -U today --no-pager 2>/dev/null | tail -n 5000 >> "$LOGBUF" || true
fi
# Nginx errors (if present)
if [[ -f /var/log/nginx/error.log ]]; then
awk -v d="$(date -d 'yesterday' '+%Y/%m/%d')" '$0 ~ d {print}' /var/log/nginx/error.log | tail -n 5000 >> "$LOGBUF" || true
fi
# Deduplicate noisy lines
sort "$LOGBUF" | uniq -c | sort -nr | head -n 200 > "$WORKDIR/top-errors-$YDATE.txt"
# Build short context (keep under ~12KB)
head -c 12000 "$WORKDIR/top-errors-$YDATE.txt" > "$WORKDIR/context-$YDATE.txt"
}
ask_llm() {
local prompt_file="$1"
jq -n \
--arg model "$MODEL" \
--arg sys "You are a pragmatic SRE assistant. Summarize recurring errors, spot new patterns, suggest 3-5 concrete next steps. Keep it concise and scannable." \
--rawfile usr "$prompt_file" \
'{
model: $model,
messages: [
{role:"system", content:$sys},
{role:"user", content:$usr}
],
temperature: 0.2
}' \
| curl -sS https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer '"$OPENAI_API_KEY"'" \
--connect-timeout 10 --max-time 60 \
-d @- \
| jq -r '.choices[0].message.content // "No content"'
}
main() {
collect_logs
{
echo "# Daily Log Brief – $YDATE"
echo
echo "Top error snippets (local aggregation):"
echo
sed -E 's/[A-Fa-f0-9]{8,}/<HASH>/g' "$WORKDIR/top-errors-$YDATE.txt" | head -n 50 | sed 's/^/ /'
echo
echo "AI Summary:"
echo
ask_llm "$WORKDIR/context-$YDATE.txt"
echo
echo "_Generated: $(date -u +"%F %T UTC")_"
} > "$REPORT"
echo "Wrote $REPORT"
}
main "$@"
Schedule with cron (Debian/Ubuntu):
crontab -e
# Add:
15 6 * * * /usr/local/bin/log-brief.sh >> /var/log/log-brief.log 2>&1
Or as a systemd timer (recommended for reliability):
# /etc/systemd/system/log-brief.service
[Unit]
Description=Daily log brief
[Service]
Type=oneshot
ExecStart=/usr/local/bin/log-brief.sh
# /etc/systemd/system/log-brief.timer
[Unit]
Description=Run daily log brief at 06:15
[Timer]
OnCalendar=*-*-* 06:15:00
Persistent=true
[Install]
WantedBy=timers.target
# Enable
sudo systemctl daemon-reload
sudo systemctl enable --now log-brief.timer
Optional: Post to Slack via incoming webhook.
curl -X POST -H 'Content-type: application/json' \
--data "$(jq -Rs --arg pretext "Daily Log Brief $YDATE" '{text: $pretext + "\n```" + . + "```"}' < "$REPORT")" \
https://hooks.slack.com/services/TOKEN/REPLACE/ME
Case Study 2: Turn Recordings into Searchable Notes
Problem: Meeting and support call recordings are underused because they’re locked in audio. We’ll transcribe locally using Whisper, then generate a crisp summary.
Install Whisper (requires Python/pip and ffmpeg):
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y ffmpeg python3 python3-pip
pip3 install -U openai-whisper torch --index-url https://download.pytorch.org/whl/cpu
- Fedora/RHEL/CentOS (dnf):
sudo dnf install -y ffmpeg python3 python3-pip
pip3 install -U openai-whisper torch --index-url https://download.pytorch.org/whl/cpu
- openSUSE (zypper):
sudo zypper install -y ffmpeg python3 python3-pip
pip3 install -U openai-whisper torch --index-url https://download.pytorch.org/whl/cpu
Transcribe a folder of audio files:
#!/usr/bin/env bash
set -euo pipefail
MODEL_SIZE="${WHISPER_MODEL:-base}" # tiny, base, small, medium, large
LANG="${LANGUAGE:-en}"
for f in "$@"; do
echo "Transcribing: $f"
whisper "$f" --model "$MODEL_SIZE" --language "$LANG" --task transcribe --output_format txt
done
echo "Done. Generated .txt files next to audio."
Optional: Summarize transcripts with an LLM:
#!/usr/bin/env bash
set -euo pipefail
: "${OPENAI_API_KEY:?Set OPENAI_API_KEY}"
MODEL="${OPENAI_MODEL:-gpt-4o-mini}"
for t in *.txt; do
SUMMARY="$(jq -n \
--arg model "$MODEL" \
--arg sys "You create action-oriented meeting notes with bullet points, decisions, owners, and deadlines. Be concise." \
--rawfile usr "$t" \
'{model:$model,messages:[{role:"system",content:$sys},{role:"user",content:$usr}],temperature:0.2}' \
| curl -sS https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer '"$OPENAI_API_KEY"'" \
--connect-timeout 10 --max-time 60 \
-d @- \
| jq -r '.choices[0].message.content')"
echo "$SUMMARY" > "${t%.txt}.summary.md"
echo "Wrote ${t%.txt}.summary.md"
done
Tips:
For long recordings, run Whisper with the “small” model first (faster) and only re-run with “medium/large” if needed.
Redact PII locally before summarizing to control exposure.
Case Study 3: OCR Invoices to Validated JSON
Problem: Accounting teams spend hours retyping vendor name, invoice number, date, and totals. We’ll use Tesseract for OCR, then ask an LLM to extract a clean JSON payload for your ERP.
Install (OCR and PDF tools):
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y tesseract-ocr poppler-utils jq
- Fedora/RHEL/CentOS (dnf):
sudo dnf install -y tesseract poppler-utils jq
- openSUSE (zypper):
sudo zypper install -y tesseract poppler-tools jq
Script: ocr-invoice.sh
#!/usr/bin/env bash
set -euo pipefail
: "${OPENAI_API_KEY:?Set OPENAI_API_KEY}"
MODEL="${OPENAI_MODEL:-gpt-4o-mini}"
in="$1"
work="${WORKDIR:-/tmp/invoice-ocr-$$}"
mkdir -p "$work"
to_text() {
local src="$1"
if [[ "$src" =~ \.pdf$ ]]; then
pdftoppm -png -r 300 "$src" "$work/page"
for img in "$work"/page-*.png; do
tesseract "$img" "$img" -l eng --psm 6 >/dev/null 2>&1
done
cat "$work"/page-*.png.txt
else
tesseract "$src" "$work/scan" -l eng --psm 6 >/dev/null 2>&1
cat "$work/scan.txt"
fi
}
TEXT="$(to_text "$in" | sed -E 's/([0-9]{4})[0-9]{6,}([0-9]{2,4})/\1…REDACTED…\2/g' | head -c 16000)"
PAYLOAD="$(jq -n \
--arg model "$MODEL" \
--arg sys "You extract invoice fields from OCR text and return strict JSON. If unknown, use null." \
--argjson schema '{
vendor_name:"string",
invoice_no:"string",
invoice_date:"YYYY-MM-DD",
total_amount:"number",
currency:"ISO-4217"
}' \
--arg txt "$TEXT" \
'{
model: $model,
messages: [
{role:"system", content:$sys},
{role:"user", content:
("Extract this JSON with keys: " + ($schema|tostring) +
". Return only JSON, no prose.\n\nOCR:\n" + $txt)
}
],
temperature: 0
}' \
| curl -sS https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer '"$OPENAI_API_KEY"'" \
--connect-timeout 10 --max-time 60 \
-d @- \
| jq -r '.choices[0].message.content' )"
# Validate and normalize JSON
echo "$PAYLOAD" | jq '{
vendor_name: .vendor_name // null,
invoice_no: .invoice_no // null,
invoice_date: .invoice_date // null,
total_amount: (try (.total_amount|tonumber) catch null),
currency: .currency // null,
source: "'"$in"'"
}'
Usage:
./ocr-invoice.sh ./samples/invoice-001.pdf > invoice-001.json
Tips:
Add vendor-specific rules (e.g., sed to normalize “Total” variants) before calling the LLM.
For large PDFs, sample key pages (first/last, pages near “Total”) to reduce cost.
Actionable Practices That Make AI Automation Work
1) Minimize and pre-structure data locally
Filter, dedup, and truncate with awk/sed/sort before any API call.
Redact PII or hashes locally. Only send what the model truly needs.
2) Treat prompts as specs
Write short, explicit instructions and enforce output formats (e.g., “return only JSON”).
Validate responses with jq and fail closed on parse errors.
3) Put guardrails on cost and reliability
Limit input bytes; chunk long texts.
Use curl timeouts and retries; log failures to a dead-letter queue (a folder).
Cache results for deterministic inputs (hash the input and skip rework).
4) Ship like any other ops task
Run via systemd timers, capture logs to journald, and export metrics (counts, durations, costs).
Keep secrets in environment files with locked-down permissions.
5) Start small, measure outcomes
Track time saved and error rates before/after.
Expand only after a stable win on a narrow workflow.
Conclusion and Next Steps
You don’t need a new platform to get AI value. With a few CLI tools and careful prompts, you can:
Triage logs while you sleep
Turn recordings into notes in minutes
Convert invoices into validated JSON
Pick one case study, run it on a small batch, and iterate. As your confidence grows, wire it into your daily jobs and notify your team via Slack or email.
If you want to go further:
Add unit tests around your Bash functions and jq validators
Introduce per-project API budgets
Explore local or self-hosted models later, after the workflow proves itself
Your terminal is already an AI ops console—now it just needs a few scripts.