Posted on
Artificial Intelligence

Using Artificial Intelligence to Organise Shell Scripts

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

Using Artificial Intelligence to Organise Shell Scripts

Ever opened your ~/bin or scripts/ folder and felt a wave of shame? Duplicate utilities. Half-documented one-offs. Mysterious files called new.sh, new2.sh, new_final.sh. You’re not alone.

Here’s the good news: AI is very good at reading, classifying, summarising, and proposing refactors for small bits of code like shell scripts. Combined with your usual command-line toolbox, an AI-assisted tidy-up can turn that junk drawer into a maintainable toolkit in an afternoon.

This guide shows you how to:

  • Inventory and categorise scripts with one command

  • Generate headers/READMEs from your existing code

  • Enforce style and explain lint warnings

  • Detect duplicates and consolidate

  • (Optional) Build a semantic search index of your scripts

We’ll keep humans in the loop and everything in Git so it’s reversible and auditable.


Why AI for shell scripts?

  • Pattern recognition: LLMs excel at inferring “what this script does” from a few lines and comments.

  • Documentation drafting: From code to crisp headers and task-focused READMEs in one prompt.

  • Safer changes with static tools: Use shfmt and ShellCheck for guardrails; let AI suggest, you approve.

  • Time to value: You’ll get 80% of the benefit by classifying and documenting—before any refactors.


Install the essentials

We’ll use standard CLI helpers plus a vendor-neutral AI CLI called llm (by Simon Willison) that talks to multiple models/providers. Choose your distro’s package manager below.

Note:

  • Debian/Ubuntu package for fd is fd-find (binary is fdfind). We’ll add a small alias to call it fd.

  • After installing pipx, you may need to restart your shell or run pipx ensurepath.

apt (Debian/Ubuntu)

sudo apt update
sudo apt install -y git ripgrep fd-find fzf jq shellcheck shfmt python3-pipx

# Optional: make 'fd' available as 'fd' instead of 'fdfind'
echo 'alias fd=fdfind' >> ~/.bashrc
. ~/.bashrc

# Ensure pipx is on your PATH
pipx ensurepath
. ~/.bashrc

dnf (Fedora/RHEL-based)

sudo dnf install -y git ripgrep fd-find fzf jq ShellCheck shfmt pipx

# Ensure pipx is on your PATH (new shell recommended)
pipx ensurepath
. ~/.bashrc

zypper (openSUSE)

sudo zypper refresh
sudo zypper install -y git ripgrep fd fzf jq ShellCheck shfmt pipx

# Ensure pipx is on your PATH
pipx ensurepath
. ~/.bashrc

Install the AI CLI

llm supports multiple providers and plugins. We’ll use OpenAI here as an example; you can swap providers/plugins later.

pipx install llm
llm install llm-openai

# Set your API key (or export OPENAI_API_KEY)
llm keys set openai
# Paste your key when prompted

Tip: Run llm models and llm -m <model> "hello" to verify connectivity.


Before you begin: put it under Git

Even if it’s a messy folder, wrap it in version control so you can revert.

cd /path/to/your/scripts
git init
git add .
git commit -m "Baseline: messy scripts before AI-assisted tidy-up"

Pro tip: Work on a branch.

git switch -c organise-with-ai

1) Inventory and categorise your scripts

We’ll ask AI to propose a folder plan, but we’ll generate a dry-run “plan.sh” so you can inspect every move.

# Pick the right 'fd' on your system
FD=$(command -v fd || command -v fdfind)

# List shell-like files
$FD -e sh -e bash -e zsh -t f --strip-cwd-prefix . > scripts.txt

# Ask AI to group scripts by purpose (JSON output)
llm -m gpt-4o-mini -s "Categorize these shell scripts by purpose. Output STRICT JSON: {\"category\": [\"path1\", ...]}. Use 5–8 sensible categories like backup, deploy, system, text, net, monitoring, misc. Only include files you received. No commentary." < scripts.txt > categories.json

Review categories.json, then turn it into a move plan:

jq -r '
  to_entries[] | .key as $c |
  .value[] |
  "mkdir -p \"" + $c + "\" && git mv \"" + . + "\" \"" + $c + "/\""
' categories.json > plan.sh

# Inspect the plan first
sed -n '1,50p' plan.sh

# Execute when happy
bash -x plan.sh
git commit -m "Organize scripts by AI-proposed categories"

If something looks off, edit categories.json or plan.sh and rerun.


2) Auto-generate headers and a README (safely)

Let AI draft a concise, commented header for each script (purpose, usage, options). We’ll insert it right under the shebang if present.

FD=$(command -v fd || command -v fdfind)

for f in $($FD -e sh -e bash -e zsh -t f); do
  echo "Annotating: $f"
  llm -m gpt-4o-mini -s "Write a concise commented header for this shell script: purpose, usage, required env vars, and example invocations. Output ONLY lines starting with '# ' and keep it under 12 lines. Do not echo code." < "$f" > "$f.header"

  awk '
    NR==1 && $0 ~ /^#!/ { print; system("cat "'"$f.header"'"); next }
    NR==1 && $0 !~ /^#!/ { system("cat "'"$f.header"'"); }
    { print }
  ' "$f" > "$f.tmp" && mv "$f.tmp" "$f"
  rm -f "$f.header"
done

git commit -am "Add AI-generated headers to scripts"

You can also ask for a per-folder README summarising contents:

# Generate a top-level README from directory listing and selected scripts
$FD -e sh -e bash -e zsh -t f | head -n 50 > sample.txt
llm -m gpt-4o-mini -s "From these filenames and their content, write a README.md describing what lives here, how to run common tasks, and any prerequisites. Use concise Markdown." --system "Be precise and conservative; do not invent features." $(cat sample.txt) > README.md

git add README.md && git commit -m "Add AI-generated README"

3) Format, lint, and let AI explain findings

Standardise style, then lint. Use AI to help understand what to fix (you still choose how).

# Reformat in-place (2-space indent, POSIX-friendly)
shfmt -w -i 2 -bn -ci -sr .

# Lint and capture JSON
FD=$(command -v fd || command -v fdfind)
shellcheck -f json $($FD -e sh -e bash -e zsh -t f) > sc.json

# Ask AI to prioritise and explain top issues with suggested fixes
jq '.[0:40]' sc.json | llm -m gpt-4o-mini -s "Explain and prioritise these ShellCheck findings. For each, include: file, line, rule, why it matters, and a minimal safe fix. Output concise Markdown bullets." > shellcheck_report.md

git add shellcheck_report.md && git commit -m "Explain ShellCheck findings"

If you want proposed patches, keep it under strict review:

# Example: propose a unified diff for ONE file (safer than batch)
FILE=path/to/script.sh
{ echo "Propose a minimal unified diff to fix ShellCheck issues in $FILE."
  echo "Do not change behavior. Only output a valid diff."
  echo
  echo "=== FILE CONTENTS START ==="
  cat "$FILE"
  echo "=== FILE CONTENTS END ==="
} | llm -m gpt-4o-mini > patch.diff

# Review carefully, then apply
git apply --reject --whitespace=fix patch.diff
git add -A && git commit -m "Apply AI-proposed minimal fixes to $FILE"

4) Detect duplicates and consolidate

First, find exact or near-exact copies (ignoring comments/blank lines):

FD=$(command -v fd || command -v fdfind)
tmp=checksums.txt
: > "$tmp"

while IFS= read -r f; do
  norm=$(sed -E 's/#.*$//' "$f" | awk 'NF' | sed -E 's/[[:space:]]+/ /g')
  printf "%s  %s\n" "$(printf "%s" "$norm" | sha1sum | awk "{print \$1}")" "$f" >> "$tmp"
done < <($FD -e sh -e bash -e zsh -t f)

sort "$tmp" | awk '
  { count[$1]++; files[$1]=files[$1]" "$2 }
  END { for (h in count) if (count[h]>1) print h ":" files[h] }
'

For “similar but not identical,” pick a suspicious pair and ask AI to propose a unified script with flags:

A=category/cleanup_tmp.sh
B=category/purge_temp_files.sh

llm -m gpt-4o-mini -s "Compare these two scripts and propose one parameterized script that subsumes both. List required flags, backward-compatibility notes, and a migration checklist. Be minimal and safe." "$A" "$B" > consolidate_notes.md

git add consolidate_notes.md && git commit -m "Plan: consolidate $A and $B"

Implement changes yourself or ask for a patch as in step 3 (one file at a time, with review).


5) Optional: Build a semantic index for natural-language search

Create an embeddings-powered index so you can ask, “Which script rotates logs?” and get useful hits.

Install the embeddings plugin:

llm install llm-embed-openai

Index file summaries (truncate to first ~200 lines per file to stay small):

FD=$(command -v fd || command -v fdfind)

while IFS= read -r f; do
  {
    printf "FILE: %s\n" "$f"
    sed -n '1,200p' "$f"
    echo
  }
done < <($FD -e sh -e bash -e zsh -t f) | llm embed -m text-embedding-3-small -d scripts_index

Now query:

llm similar -d scripts_index "script that backs up a Postgres database" -n 5
llm similar -d scripts_index "rotate nginx logs safely with compression" -n 5

Real-world flow (putting it together)

  • Commit your mess.

  • Run step 1 to propose categories; tweak; move with Git.

  • Run step 2 to add headers and a README.

  • Run step 3 to format/lint and understand fixes.

  • Run step 4 for duplicates and plan consolidation.

  • Optionally build the index (step 5) for Q&A.

Keep commits small and focused. If anything feels risky, branch again.


Best practices and caveats

  • Keep secrets out of prompts. Redact credentials before sending content to a remote model.

  • Human in the loop. Treat AI output as proposals; you approve via Git.

  • Prefer narrow, explicit prompts. “Only output JSON” or “Only a unified diff” reduces risk.

  • Use static tools first. shfmt and ShellCheck catch a lot without any AI.

  • Token budgets are real. Summarise large scripts or batch them.

  • For air-gapped or sensitive code, consider local models. llm supports plugins for local backends too.


Conclusion and next step

Your shell scripts are valuable operational knowledge—stop letting them rot in a junk drawer. With a few CLI tools and a careful AI workflow, you can organise, document, and harden them fast—and keep it all auditable in Git.

Your next step:

  • Pick one directory.

  • Run the inventory and category plan from step 1.

  • Add headers from step 2.

  • Commit, share the before/after with your team, and iterate.

If this saved you time, turn these snippets into a reusable organise_scripts.sh for your team and schedule it as a quarterly clean-up.