AsciiDoc Grep Patterns & Exotic Syntax Reference

Two references in one: CLI patterns for analyzing AsciiDoc repositories, and a living showcase of exotic AsciiDoc syntax features with real examples.

Grep Patterns for AsciiDoc Analysis

Patterns for finding, counting, and categorizing diagram usage across an Antora multi-repo documentation site.

Find All Pages Containing Diagrams

Files only (-l)
grep -r "image::diagrams/" docs/modules/ROOT/pages --include="*.adoc" -l
With line numbers and context (-rn)
grep -rn "image::diagrams/" docs/modules/ROOT/pages --include="*.adoc"
Find specific diagram by name
grep -rn "claude-code-architecture" docs/modules/ROOT/pages --include="*.adoc"

Count and Rank Diagram Usage

Count per diagram file (pipe chain)
grep -roh "image::diagrams/[^[]*" docs/modules/ROOT/pages \  (1)
  | sort \   (2)
  | uniq -c \  (3)
  | sort -rn   (4)
1 -roh: recursive, only-matching, no-filename — extracts raw image:: references
2 sort: alphabetical sort required before uniq (it only compares adjacent lines)
3 uniq -c: counts consecutive identical lines
4 sort -rn: reverse numeric sort — highest count first
Same thing in awk (single-pass, no double sort)
grep -roh "image::diagrams/[^[]*" docs/modules/ROOT/pages \
  | awk '{a[$0]++} END {for (k in a) printf "%5d %s\n", a[k], k}' \
  | sort -rn

Count by Category

Extract category directory with awk field splitting
grep -roh "image::diagrams/[^[]*" docs/modules/ROOT/pages \
  | awk -F'/' '{
      dir=$3
      if ($4 !~ /\.(svg|png)$/) dir=dir"/"$4  (1)
      print dir
    }' \
  | sort | uniq -c | sort -rn
1 Handles variable-depth paths: diagrams/d2/security/file.svg (4 segments) vs diagrams/monad/file.svg (3 segments)

Widen the Net

AsciiDoc repos may also use Kroki blocks and include directives for diagrams, not just image::.

Find all diagram-related patterns
grep -rnE "(image::diagrams/|\[d2\]|\[mermaid\]|\[plantuml\]|include::example\\\$diagrams/)" \
  docs/modules/ROOT/pages --include="*.adoc"

Results Snapshot (2026-03-27)

Click to see full file listing (31 files)
docs/modules/ROOT/pages/2026/02/WRKLOG-2026-02-13.adoc
docs/modules/ROOT/pages/2026/02/WRKLOG-2026-02-16.adoc
docs/modules/ROOT/pages/2026/02/WRKLOG-2026-02-18.adoc
docs/modules/ROOT/pages/2026/02/WRKLOG-2026-02-23.adoc
docs/modules/ROOT/pages/trackers/personal-2026-02.adoc
docs/modules/ROOT/pages/trackers/work-2026-02.adoc
docs/modules/ROOT/pages/reference/diagrams/architecture.adoc
docs/modules/ROOT/pages/reference/diagrams/network.adoc
docs/modules/ROOT/pages/reference/diagrams/security.adoc
docs/modules/ROOT/pages/reference/diagrams/flows.adoc
docs/modules/ROOT/pages/reference/diagrams/projects.adoc
docs/modules/ROOT/pages/reference/diagrams/tac.adoc
docs/modules/ROOT/pages/reference/diagrams/trackers.adoc
docs/modules/ROOT/pages/reference/diagrams/monad.adoc
docs/modules/ROOT/pages/education/training/monad/pipelines/network.adoc
docs/modules/ROOT/pages/education/training/monad/pipelines/ftd.adoc
docs/modules/ROOT/pages/education/training/monad/pipelines/ise.adoc
docs/modules/ROOT/pages/education/training/monad/index.adoc
docs/modules/ROOT/pages/education/training/monad/routing.adoc
docs/modules/ROOT/pages/education/training/monad/transforms.adoc
docs/modules/ROOT/pages/projects/chla/siem-qradar-to-sentinel/index.adoc
docs/modules/ROOT/pages/projects/chla/siem-qradar-to-sentinel/monad-evaluation.adoc
docs/modules/ROOT/pages/projects/chla/PRJ-ipsk-manager-ha.adoc
docs/modules/ROOT/pages/projects/personal/claude-code-features/index.adoc
docs/modules/ROOT/pages/case-studies/tac/TAC-2026-03-chla-8021x-auth-failures.adoc
docs/modules/ROOT/pages/case-studies/incidents/PREP-2026-03-16-ise-incident-defense.adoc
docs/modules/ROOT/pages/case-studies/changes/CR-2026-03-25-claude-code-hooks-enhancement.adoc
docs/modules/ROOT/pages/case-studies/changes/CR-2026-03-26-antora-aurora-ocean-themes.adoc
docs/modules/ROOT/pages/case-studies/rca/RCA-2026-03-13-001-wifi-dhcp-failure.adoc
docs/modules/ROOT/pages/case-studies/deployments/DEPLOY-2026-02-14-xianming-ding-linux-ad-auth.adoc
docs/modules/ROOT/pages/case-studies/templates/deployment-template.adoc
Click to see usage counts (top reused diagrams)
      3 image::diagrams/d2/tac/tac-8021x-auth-failure.svg
      3 image::diagrams/d2/security/ipsk-ha-architecture.svg
      3 image::diagrams/d2/architecture/monad-architecture.svg
      2 image::diagrams/monad/transform-chain.svg
      2 image::diagrams/monad/routing-conditions.svg
      2 image::diagrams/monad/pipeline-architecture.svg
      2 image::diagrams/monad/network-pipeline.svg
      2 image::diagrams/monad/network-environment.svg
      2 image::diagrams/monad/ise-pipeline.svg
      2 image::diagrams/monad/ise-environments.svg
      2 image::diagrams/monad/ftd-pipeline.svg
      2 image::diagrams/monad/ftd-environment-v2.svg
      2 image::diagrams/monad/data-transformation-flow-v2.svg
      2 image::diagrams/d2/trackers/work-tracker-v7-dark.svg
      2 image::diagrams/d2/trackers/work-tracker-2026-02-compact.svg
      2 image::diagrams/d2/trackers/personal-tracker-2026-02.svg
      2 image::diagrams/d2/security/defense-in-depth.svg
      2 image::diagrams/d2/security/dacl-solution-dot.svg
      2 image::diagrams/d2/security/dacl-problem-dot.svg
      2 image::diagrams/d2/projects/wazuh-deployment-2026-02-23.svg
      2 image::diagrams/d2/projects/claude-code-hooks-flow.svg
      2 image::diagrams/d2/flows/nmcli-wifi-workflow.svg
      2 image::diagrams/d2/flows/eap-tls-auth-flow.svg
      2 image::diagrams/d2/architecture/ise-home-deployment.svg
      2 image::diagrams/d2/architecture/ise-distributed-deployment.svg
      2 image::diagrams/d2/architecture/claude-code-architecture.svg
      2 image::diagrams/d2/architecture/antora-theme-system.svg

87 total diagram references. 27 diagrams used 2+ times. 60 single-use (mostly v1/v2 pairs in the reference gallery).

Heredoc Patterns for Capturing CLI Sessions

Patterns for documenting commands and their output in AsciiDoc format directly from the terminal.

Batch Append with Heredoc

cat >> file.adoc << 'EOF'   (1)

== Section Title

.Description
[source,bash]

command here

EOF                          (2)
1 'EOF' (quoted) prevents all shell expansion — $VARIABLES and backticks stay literal
2 Closing EOF must be flush-left: no spaces, no tabs, nothing after it

Capture Command Output + Append

OUTPUT=$(grep -roh "pattern" dir) && \   (1)
cat >> file.adoc << EOF                  (2)

.Command
[source,bash]
----
grep -roh "pattern" dir
----

.Output
[source]
----
$OUTPUT                                  (3)
----
EOF
1 Capture output to variable first — before touching the file
2 Unquoted EOF so $OUTPUT expands
3 Variable expands to the captured result
Never read a file and append to the same file in one pipeline. Capture to a variable first, then append. Reading and writing simultaneously causes recursion or data loss.

Chain with Sed for Pre-Cleanup

sed -i '66d' file.adoc && \   (1)
cat >> file.adoc << 'EOF'     (2)
New content here
EOF
1 Delete line 66, then append only if delete succeeds
2 && ensures heredoc runs only on success

AsciiDoc Exotic Syntax Showcase

Collapsible Blocks

Click to reveal the grep cheatsheet
Flag Purpose

-r

Recursive search

-n

Show line numbers

-l

Files with matches only

-c

Count matches per file

-o

Only matching portion

-h

Suppress filename

-P

Perl-compatible regex (PCRE)

-E

Extended regex (ERE)

-v

Invert match

-w

Whole word match

Starts open, user can collapse

This block starts open but can be collapsed. Use for content that’s important but lengthy.

Admonition Blocks

Single-line admonition. Quick note inline.
Use grep -roh when you only need the matching text for piping into sort | uniq -c.
Never echo >> file and sed the same file in a pipeline. Race condition.
Heredoc EOF must be flush-left. No leading spaces or tabs.
Always capture command output to a variable before appending to the same file.
Expanded admonition with title and rich content

When using unquoted EOF in heredocs:

  • $VARIABLES will be expanded

  • Backticks will be interpreted

  • Use 'EOF' (quoted) to prevent all expansion

# Quoted - literal output
cat << 'EOF'
$HOME stays literal
EOF

# Unquoted - variables expand
cat << EOF
$HOME becomes /home/username
EOF

Sidebar Blocks

Why awk beats grep | sort | uniq -c

The classic grep -oh pattern | sort | uniq -c | sort -rn spawns 4 processes and sorts twice.

awk does it in a single pass with associative arrays:

awk '/pattern/ {a[$0]++} END {for (k in a) print a[k], k}' file

One process. O(n) time. No sorting until the END block.

Use the pipe chain when exploring. Use awk when scripting.

Quote Blocks

Unix is simple. It just takes a genius to understand its simplicity.
— Dennis Ritchie

Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.

— Doug McIlroy
The Unix Philosophy

Code Block Callouts

grep -roh "image::diagrams/[^[]*" docs/modules/ROOT/pages \  (1)
  | awk -F'/' '{print $3"/"$4}' \  (2)
  | sort \  (3)
  | uniq -c \  (4)
  | sort -rn  (5)
1 -roh: recursive, only-matching, no-filename — extracts raw matches
2 awk -F'/': splits on /, prints fields 3 and 4 as category
3 sort: alphabetical sort required before uniq
4 uniq -c: counts consecutive identical lines (hence the sort)
5 sort -rn: reverse numeric sort — highest count first
OUTPUT=$(sed -n '58,$p' file.adoc)  (1)
cat >> file.adoc << EOF              (2)
$OUTPUT                              (3)
EOF                                  (4)
1 Capture before appending — avoids self-referential recursion
2 Unquoted EOF allows variable expansion
3 $OUTPUT expands to the captured content
4 Closing delimiter must be flush-left, no trailing characters

Tables with AsciiDoc Content in Cells

Feature Example

Collapsible

Expand me

Hidden content inside a table cell.

List

  • Item one

  • Item two

    • Nested item

  • Item three

Code

awk 'NR==66' file.adoc

Admonition

You can nest admonitions inside a| cells.

Column and Row Spans

Col A Col B Col C

This cell spans all 3 columns

This cell spans 2 rows

B1

C1

B2

C2

A3

This spans columns B and C

CSV Table Import

Command Flag Purpose

grep

-r

Recursive

grep

-o

Only matching

grep

-h

No filename

grep

-P

PCRE regex

sed

-i

In-place edit

sed

-n

Suppress output

awk

-F

Field separator

UI Macros

Requires :experimental: in the document header.

Keyboard shortcuts: Ctrl+C to cancel, Ctrl+Z to suspend, Ctrl+R for reverse search.

Menu navigation: File  Save As…​  AsciiDoc

Button: Press Submit to continue.

Combine them: Press Ctrl+Shift+P then select Terminal  Run Task  Build.

Description Lists

Horizontal Layout

grep -r

Recursive search through directories

sed -i

In-place file editing

awk -F

Set field delimiter

find -exec

Execute command on matches

Q&A Style

  1. Why does sort come before uniq -c?

    uniq only compares adjacent lines. Without sort, identical non-adjacent lines are counted separately.

  2. Why use 'EOF' (quoted) vs EOF (unquoted)?

    Quoted prevents all shell expansion inside the heredoc. Unquoted allows $VAR, backticks, and \ escaping.

  3. When to use && vs ; between commands?

    && short-circuits: second command runs only if first succeeds (exit 0). ; runs both regardless. Use && for dependent operations, ; for independent ones.

Discrete Headings and Text Roles

This heading appears styled but is NOT in the sidebar TOC

Regular paragraph after a discrete heading.

This paragraph renders larger as a lead/intro paragraph. Use it for section summaries or key takeaways.

Centered text block.

Right-aligned text block.

Mark text as highlighted using the hash syntax.

Mark text as underlined using a role.

Mark text as strikethrough using a role.

Footnotes

The grep command supports three regex flavors: BRE (default), ERE (-E), and PCRE (-P).[1] Most Linux distributions ship GNU grep.[2]

PCRE enables lookahead and lookbehind assertions.[2]

Conditional Content

This content renders everywhere except GitHub.

Counters

Step 1: Run the grep command to find matches.
Step 2: Pipe output through awk for field extraction.
Step 3: Sort and count with sort | uniq -c.
Step 4: Capture output to variable before heredoc append.
Step 5: Verify the file looks clean.

Open Blocks

This is an open block rendered as a sidebar. Open blocks (--) are the most versatile delimiter — they take on the behavior of whatever role or style you assign.

This renders as an example block using the open block delimiter. Useful when your content contains other delimiters that would conflict.

Passthrough

Pass inline HTML: highlighted with raw HTML mark tag

Pass with attributes: bold inside passthrough

Literal Block (preserves whitespace exactly)

/home/evanusmodestus/
β”œβ”€β”€ atelier/
β”‚   └── _bibliotheca/
β”‚       β”œβ”€β”€ domus-captures/     ← you are here
β”‚       β”œβ”€β”€ domus-docs/         ← hub aggregator
β”‚       └── domus-infra-ops/    ← infra runbooks
└── .claude/
    └── CLAUDE.md

Listing Block vs Source Block

Listing block (no syntax highlighting)
This is a listing block.
No language, no highlighting.
Good for generic preformatted text.
Source block (with highlighting)
diagram_count = {}
for line in open("results.txt"):
    name = line.strip().split("/")[-1]
    diagram_count[name] = diagram_count.get(name, 0) + 1

Inline Icons

Requires :icons: font in the document header.

Hot tip: combine grep -P with lookaheads for surgical matching.

Completed Failed Warning

Terminal Code Documentation

GitHub Linux Secrets

Session Log

Lessons learned during the session that produced this document
Commands practiced
  • echo >> to append breadcrumbs (messy but works — heredocs are better)

  • sed -n 'Np' to inspect specific lines

  • sed -i '66d' to delete a single line (form feed character)

  • sed -i '63,$d' to nuke from line 63 to end of file

  • Heredoc cat >> file << 'EOF' for batch append in proper AsciiDoc format

  • Glob patterns docs/mod*/R*/_dr*/unix* instead of typing full paths

  • Variable capture + heredoc for command + output documentation

Gotchas discovered
  • \f in echo produces a form feed control character — watch escape sequences

  • Heredoc closing EOF must be on its own line with no leading spaces

  • Heredoc content is file content, not executed commands — don’t paste shell instructions

  • && chains ensure second command only runs if first succeeds

  • Reading a file’s tail and appending it back to the same file causes recursive duplication

  • blink.cmp needs snippets = { preset = "luasnip" } to actually use LuaSnip snippets


1. PCRE requires GNU grep compiled with libpcre. BSD grep on macOS does not support -P.
2. Arch Linux, Ubuntu, Fedora all include PCRE support in their default grep package.