@hybridlabor-api/aos 4.8.0 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/{agents.md → AGENTS.md} +3 -1
- package/.agents/nodes.json +3 -1
- package/.agents/vendor-manifest.json +23 -1
- package/.claude/agents/godmode-media-eventtech.md +1 -1
- package/.claude/hooks/conventional-commits.mjs +125 -0
- package/.claude/hooks/env-file-protection.mjs +105 -0
- package/.claude/hooks/go-gate.mjs +101 -81
- package/.claude/hooks/memb-inject.mjs +29 -1
- package/.claude/settings.json +13 -0
- package/.claude/workflows/startcycle-dispatch.mjs +23 -1
- package/.opencode/agents/godmode-media-eventtech.md +1 -1
- package/.opencode/plugins/bdb-aos.js +31 -4
- package/CLAUDE.md +0 -571
- package/README.de.md +1 -1
- package/README.md +1 -1
- package/README.pt.md +1 -1
- package/THIRD_PARTY_NOTICES.md +126 -0
- package/bin/aos-doctor.mjs +1 -1
- package/docs/skills_table.md +1 -1
- package/installer.js +187 -55
- package/package.json +7 -3
- package/packages/aos-cli/README.md +80 -0
- package/packages/aos-cli/bin/aos-cli.mjs +134 -0
- package/packages/aos-cli/core-skills.json +12 -0
- package/packages/aos-cli/extensions/aos.ts +321 -0
- package/packages/aos-cli/package-lock.json +1923 -0
- package/packages/aos-cli/package.json +29 -0
- package/packages/aos-cli/scripts/check-theme.mjs +63 -0
- package/packages/aos-cli/themes/aos.json +97 -0
- package/scripts/build-plugin-manifest.mjs +131 -0
- package/scripts/validate-skills.mjs +81 -6
- package/skills/basic/ao-orchestrator/SKILL.md +116 -0
- package/skills/basic/bdb-eventagency-skill/SKILL.md +252 -0
- package/skills/basic/bdb-shipping-skill/SKILL.md +161 -0
- package/skills/basic/godmode-eventtech/SKILL.md +4 -1
- package/skills/global_config/agenttrail/SKILL.md +6 -1
- package/skills/global_config/aos-project-init/SKILL.md +2 -0
- package/skills/global_config/aos-project-init/assets/AGENTS.template.md +1 -1
- package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +1 -1
- package/skills/global_config/aos-setup/SKILL.md +1 -1
- package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +1 -1
- package/skills/global_config/ask-tim/SKILL.md +7 -7
- package/skills/global_config/bash-script-generator/SKILL.md +201 -0
- package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
- package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
- package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
- package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
- package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
- package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
- package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
- package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
- package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
- package/skills/global_config/bash-script-validator/SKILL.md +249 -0
- package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
- package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
- package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
- package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
- package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
- package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
- package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
- package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
- package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
- package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
- package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
- package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
- package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
- package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
- package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
- package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
- package/skills/global_config/ci-pipeline/SKILL.md +135 -0
- package/skills/global_config/deja-memory/SKILL.md +3 -1
- package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
- package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
- package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
- package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
- package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
- package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
- package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
- package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
- package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
- package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
- package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
- package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
- package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
- package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
- package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
- package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
- package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
- package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
- package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
- package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
- package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
- package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
- package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
- package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
- package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
- package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
- package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
- package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
- package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
- package/skills/global_config/github-actions-generator/SKILL.md +353 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
- package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
- package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
- package/skills/global_config/github-actions-generator/examples/README.md +147 -0
- package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
- package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
- package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
- package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
- package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
- package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
- package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
- package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
- package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
- package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
- package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
- package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
- package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
- package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
- package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
- package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
- package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
- package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
- package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
- package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
- package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
- package/skills/global_config/github-actions-templates/SKILL.md +7 -0
- package/skills/global_config/github-actions-validator/SKILL.md +576 -0
- package/skills/global_config/github-actions-validator/examples/README.md +88 -0
- package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
- package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
- package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
- package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
- package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
- package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
- package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
- package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
- package/skills/global_config/github-actions-validator/references/runners.md +317 -0
- package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
- package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
- package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
- package/skills/global_config/makefile-generator/SKILL.md +614 -0
- package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
- package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
- package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
- package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
- package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
- package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
- package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
- package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
- package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
- package/skills/global_config/makefile-validator/SKILL.md +244 -0
- package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
- package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
- package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
- package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
- package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
- package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
- package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
- package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
- package/skills/global_config/plan-canvas/SKILL.md +9 -2
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/ui.js +10 -2
- package/skills/global_config/plan-canvas/scripts/plan-canvas.js +1 -1
- package/skills/global_config/read-the-damn-docs/SKILL.md +175 -0
- package/skills/global_config/requesting-code-review/SKILL.md +98 -0
- package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
- package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
- package/skills/global_config/verification-before-completion/SKILL.md +123 -0
- package/skills/global_config/writing-plans/SKILL.md +126 -46
- package/skills/global_config/writing-plans-legacy/SKILL.md +152 -0
- package/.claude/CLAUDE.md +0 -12
- package/mcps/RhinoMCP/docs/content/docs/getting-started/gemini.md +0 -61
- /package/{GEMINI.md → RULES.md} +0 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bash-script-validator
|
|
3
|
+
description: Validate, lint, audit, or fix bash/shell/.sh scripts via ShellCheck.
|
|
4
|
+
category: engineering-method
|
|
5
|
+
source: cc-devops-skills
|
|
6
|
+
date_added: "2026-09-25"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Bash Script Validator
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
This skill validates Bash and POSIX shell scripts with layered checks:
|
|
14
|
+
|
|
15
|
+
1. Syntax validation (`bash -n` or `sh -n`)
|
|
16
|
+
2. ShellCheck static analysis (system binary or wrapper fallback)
|
|
17
|
+
3. Custom security, portability, and optimization checks
|
|
18
|
+
|
|
19
|
+
Use the default flow below, then branch to fallbacks only when the environment is constrained.
|
|
20
|
+
|
|
21
|
+
## Trigger Guidance
|
|
22
|
+
|
|
23
|
+
Use this skill when the request includes script quality, linting, syntax checking, or shell portability work.
|
|
24
|
+
|
|
25
|
+
### Trigger Phrases
|
|
26
|
+
|
|
27
|
+
- "Validate this bash script"
|
|
28
|
+
- "Lint this `.sh` file"
|
|
29
|
+
- "Find security issues in this shell script"
|
|
30
|
+
- "Why does this script fail ShellCheck?"
|
|
31
|
+
- "Make this script POSIX compliant"
|
|
32
|
+
- "Review this shell script before CI"
|
|
33
|
+
|
|
34
|
+
### Non-Trigger Examples
|
|
35
|
+
|
|
36
|
+
- General Linux command questions with no script file
|
|
37
|
+
- Kubernetes, Terraform, or pipeline validation tasks that do not involve shell scripts
|
|
38
|
+
- Pure prose editing tasks
|
|
39
|
+
|
|
40
|
+
## Deterministic Execution Model
|
|
41
|
+
|
|
42
|
+
Run commands from this skill directory:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cd devops-skills-plugin/skills/bash-script-validator
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Step 1: Preflight
|
|
49
|
+
|
|
50
|
+
1. Confirm target path exists and is readable.
|
|
51
|
+
2. Confirm `bash` is available.
|
|
52
|
+
3. Determine whether fixes can be applied directly (write access) or only suggested (read-only).
|
|
53
|
+
|
|
54
|
+
### Step 2: Run Baseline Validation (Default Path)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bash scripts/validate.sh <script-path>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
For deterministic stage behavior, set the ShellCheck provider explicitly:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Modes: auto (default), system, wrapper, disabled
|
|
64
|
+
VALIDATOR_SHELLCHECK_MODE=system bash scripts/validate.sh <script-path>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Record:
|
|
68
|
+
|
|
69
|
+
- Detected shell type
|
|
70
|
+
- Exit code (`0` clean, `1` warnings, `2` errors)
|
|
71
|
+
- All reported issue lines and ShellCheck codes (`SC####`) when present
|
|
72
|
+
|
|
73
|
+
### Step 3: Load Only Needed References
|
|
74
|
+
|
|
75
|
+
Progressive disclosure by issue type:
|
|
76
|
+
|
|
77
|
+
- ShellCheck code explanations: `docs/shellcheck-reference.md`
|
|
78
|
+
- General fix patterns and security mistakes: `docs/common-mistakes.md`
|
|
79
|
+
- Bash-only behavior: `docs/bash-reference.md`
|
|
80
|
+
- POSIX portability or bashism fixes: `docs/shell-reference.md`
|
|
81
|
+
- Text-processing optimization issues: `docs/grep-reference.md`, `docs/awk-reference.md`, `docs/sed-reference.md`, `docs/regex-reference.md` (only when directly relevant)
|
|
82
|
+
|
|
83
|
+
### Step 4: Provide or Apply Fixes
|
|
84
|
+
|
|
85
|
+
For each issue, include:
|
|
86
|
+
|
|
87
|
+
1. Exact location from validator output (line number and snippet)
|
|
88
|
+
2. Root cause
|
|
89
|
+
3. Corrected code
|
|
90
|
+
4. Why the change is safer or more portable
|
|
91
|
+
5. Subsection-level citation (format below)
|
|
92
|
+
|
|
93
|
+
If the request includes patching files and write access is available, apply fixes in small batches grouped by issue type.
|
|
94
|
+
|
|
95
|
+
### Step 5: Rerun Policy (Mandatory After Changes)
|
|
96
|
+
|
|
97
|
+
After each batch of edits, rerun the validator:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
bash scripts/validate.sh <script-path>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Rerun loop rules:
|
|
104
|
+
|
|
105
|
+
1. Continue until no new errors are introduced.
|
|
106
|
+
2. If warnings remain by design, document why they are intentionally accepted.
|
|
107
|
+
3. If constraints prevent full resolution, report unresolved items with a clear next action.
|
|
108
|
+
4. Always report the latest rerun exit code and remaining issue count.
|
|
109
|
+
|
|
110
|
+
## Fallback Behavior
|
|
111
|
+
|
|
112
|
+
Use these branches only when the default flow cannot run as-is.
|
|
113
|
+
|
|
114
|
+
| Constraint | Fallback action | Reporting requirement |
|
|
115
|
+
| --- | --- | --- |
|
|
116
|
+
| `shellcheck` missing, wrapper available | Let `scripts/validate.sh` use `scripts/shellcheck_wrapper.sh --cache` automatically | State that wrapper mode was used |
|
|
117
|
+
| `shellcheck` and wrapper unavailable | Run syntax + custom checks only (validator does this) | Explicitly call out reduced coverage and missing ShellCheck analysis |
|
|
118
|
+
| Python unavailable for wrapper | Skip wrapper path, keep syntax + custom checks | State why ShellCheck could not run |
|
|
119
|
+
| Target file is read-only | Provide precise patch suggestions without editing | Mark response as "advisory only" |
|
|
120
|
+
| Target file missing or unreadable | Stop and request a valid file path | Do not fabricate results |
|
|
121
|
+
| Binary/non-text input | Stop validation | Report unsupported input type |
|
|
122
|
+
|
|
123
|
+
## Citation Guidance for Fixes
|
|
124
|
+
|
|
125
|
+
Use subsection-level citations for every non-trivial fix.
|
|
126
|
+
|
|
127
|
+
Required citation format:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
Reference: docs/<file>.md -> <Section> -> <Subsection>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Examples:
|
|
134
|
+
|
|
135
|
+
- `Reference: docs/common-mistakes.md -> 1. Unquoted Variables -> Solution`
|
|
136
|
+
- `Reference: docs/shellcheck-reference.md -> SC2164: Use || exit After cd`
|
|
137
|
+
- `Reference: docs/shell-reference.md -> POSIX Best Practices -> 5. Avoid Bashisms`
|
|
138
|
+
|
|
139
|
+
Citation rules:
|
|
140
|
+
|
|
141
|
+
1. Cite the most specific section that justifies the fix.
|
|
142
|
+
2. For ShellCheck findings, include both the `SC####` code and the matching section.
|
|
143
|
+
3. If no exact subsection exists, cite the closest section and state that the fix is inferred from that guidance.
|
|
144
|
+
|
|
145
|
+
## Response Template
|
|
146
|
+
|
|
147
|
+
Use this structure for deterministic output:
|
|
148
|
+
|
|
149
|
+
- `Validation Results`
|
|
150
|
+
- `Command`: `bash scripts/validate.sh <script-path>`
|
|
151
|
+
- `Detected shell`: `<shell>`
|
|
152
|
+
- `Exit code`: `<code>`
|
|
153
|
+
- `Summary`: `<errors> errors, <warnings> warnings, <info> info`
|
|
154
|
+
- `Issue`: `<short label> (Line <n>)`
|
|
155
|
+
- `Problem`:
|
|
156
|
+
```bash
|
|
157
|
+
<problematic snippet>
|
|
158
|
+
```
|
|
159
|
+
- `Fix`:
|
|
160
|
+
```bash
|
|
161
|
+
<corrected snippet>
|
|
162
|
+
```
|
|
163
|
+
- `Why`: `<short explanation>`
|
|
164
|
+
- `Reference`: `docs/<file>.md -> <Section> -> <Subsection>`
|
|
165
|
+
- `Rerun command`: `bash scripts/validate.sh <script-path>`
|
|
166
|
+
- `Exit code after fixes`: `<code>`
|
|
167
|
+
- `Remaining issues`: `<count or none>`
|
|
168
|
+
|
|
169
|
+
## Example Flows
|
|
170
|
+
|
|
171
|
+
### Fully Automated Environment
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# 1) Baseline validation
|
|
175
|
+
bash scripts/validate.sh examples/bad-bash.sh
|
|
176
|
+
|
|
177
|
+
# 2) Apply fixes to target script
|
|
178
|
+
# 3) Rerun validation
|
|
179
|
+
bash scripts/validate.sh examples/bad-bash.sh
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Expected behavior: full syntax + ShellCheck + custom-check coverage, with iterative reruns until stable.
|
|
183
|
+
|
|
184
|
+
### Deterministic CI Gate
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Requires a system shellcheck binary.
|
|
188
|
+
bash scripts/run_ci_checks.sh
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
This runner enforces `VALIDATOR_REQUIRE_SHELLCHECK=1` and `VALIDATOR_SHELLCHECK_MODE=system`
|
|
192
|
+
so CI fails if the ShellCheck stage is skipped or unavailable.
|
|
193
|
+
|
|
194
|
+
### Constrained Environment (No ShellCheck Runtime)
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# shellcheck unavailable and wrapper cannot run
|
|
198
|
+
bash scripts/validate.sh examples/bad-shell.sh
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Expected behavior: syntax + custom checks still run. Report reduced coverage and list what must be revalidated once ShellCheck is available.
|
|
202
|
+
|
|
203
|
+
## Validator Script Details
|
|
204
|
+
|
|
205
|
+
### Scripts
|
|
206
|
+
|
|
207
|
+
- `scripts/validate.sh`: primary validator entrypoint
|
|
208
|
+
- `scripts/shellcheck_wrapper.sh`: optional ShellCheck fallback using a cached Python virtual environment
|
|
209
|
+
|
|
210
|
+
### Detection and Ordering
|
|
211
|
+
|
|
212
|
+
Validation order in `scripts/validate.sh`:
|
|
213
|
+
|
|
214
|
+
1. File checks (exists/readable/text)
|
|
215
|
+
2. Shebang-based shell detection
|
|
216
|
+
3. Syntax check
|
|
217
|
+
4. ShellCheck (or fallback/skip behavior)
|
|
218
|
+
5. Custom checks
|
|
219
|
+
6. Summary with exit code
|
|
220
|
+
|
|
221
|
+
### Exit Codes
|
|
222
|
+
|
|
223
|
+
- `0`: no issues found
|
|
224
|
+
- `1`: warnings found
|
|
225
|
+
- `2`: errors found
|
|
226
|
+
|
|
227
|
+
## References
|
|
228
|
+
|
|
229
|
+
Load only what is needed:
|
|
230
|
+
|
|
231
|
+
- `docs/bash-reference.md`
|
|
232
|
+
- `docs/shell-reference.md`
|
|
233
|
+
- `docs/shellcheck-reference.md`
|
|
234
|
+
- `docs/common-mistakes.md`
|
|
235
|
+
- `docs/grep-reference.md`
|
|
236
|
+
- `docs/awk-reference.md`
|
|
237
|
+
- `docs/sed-reference.md`
|
|
238
|
+
- `docs/regex-reference.md`
|
|
239
|
+
|
|
240
|
+
## Done Criteria
|
|
241
|
+
|
|
242
|
+
This skill update is complete when all are true:
|
|
243
|
+
|
|
244
|
+
1. Trigger guidance is explicit (positive and non-trigger examples).
|
|
245
|
+
2. Default workflow is deterministic and ordered.
|
|
246
|
+
3. Fallback behavior is explicit for missing tooling and constrained environments.
|
|
247
|
+
4. Fix explanations include subsection-level citations.
|
|
248
|
+
5. Post-fix rerun policy is mandatory and reported with exit codes.
|
|
249
|
+
6. Documentation supports both fully automated and constrained execution paths.
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
# GNU AWK (gawk) Reference Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
AWK is a powerful text processing language designed for pattern scanning and processing. It's particularly useful for field-based data manipulation.
|
|
6
|
+
|
|
7
|
+
**Official Manual:** https://www.gnu.org/software/gawk/manual/
|
|
8
|
+
**Man Page:** `man awk`
|
|
9
|
+
|
|
10
|
+
## Basic Syntax
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
awk 'pattern { action }' file
|
|
14
|
+
awk -F delimiter 'pattern { action }' file
|
|
15
|
+
awk -f script.awk file
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Structure
|
|
19
|
+
|
|
20
|
+
```awk
|
|
21
|
+
BEGIN { # Executed before processing }
|
|
22
|
+
pattern { # Executed for matching lines }
|
|
23
|
+
END { # Executed after processing }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Built-in Variables
|
|
27
|
+
|
|
28
|
+
### Field Variables
|
|
29
|
+
```awk
|
|
30
|
+
$0 # Entire line
|
|
31
|
+
$1 # First field
|
|
32
|
+
$2 # Second field
|
|
33
|
+
$NF # Last field
|
|
34
|
+
$(NF-1) # Second to last field
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Control Variables
|
|
38
|
+
```awk
|
|
39
|
+
NF # Number of fields in current record
|
|
40
|
+
NR # Current record number (line number)
|
|
41
|
+
FNR # Record number in current file
|
|
42
|
+
FS # Input field separator (default: whitespace)
|
|
43
|
+
OFS # Output field separator (default: space)
|
|
44
|
+
RS # Input record separator (default: newline)
|
|
45
|
+
ORS # Output record separator (default: newline)
|
|
46
|
+
FILENAME # Current filename
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Common Usage Patterns
|
|
50
|
+
|
|
51
|
+
### Basic Field Processing
|
|
52
|
+
```bash
|
|
53
|
+
# Print specific fields
|
|
54
|
+
awk '{print $1}' file.txt # First field
|
|
55
|
+
awk '{print $1, $3}' file.txt # First and third fields
|
|
56
|
+
awk '{print $NF}' file.txt # Last field
|
|
57
|
+
|
|
58
|
+
# Print with custom separator
|
|
59
|
+
awk '{print $1 ":" $2}' file.txt # Custom separator
|
|
60
|
+
awk -v OFS='\t' '{print $1, $2}' file # Tab-separated
|
|
61
|
+
|
|
62
|
+
# Print entire line with line number
|
|
63
|
+
awk '{print NR, $0}' file.txt
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Custom Field Separator
|
|
67
|
+
```bash
|
|
68
|
+
# Use comma as separator
|
|
69
|
+
awk -F',' '{print $1}' file.csv
|
|
70
|
+
|
|
71
|
+
# Use colon as separator (like /etc/passwd)
|
|
72
|
+
awk -F':' '{print $1}' /etc/passwd
|
|
73
|
+
|
|
74
|
+
# Multiple character separator
|
|
75
|
+
awk -F'::' '{print $2}' file.txt
|
|
76
|
+
|
|
77
|
+
# Regex as separator
|
|
78
|
+
awk -F'[,:]' '{print $1}' file.txt # Comma or colon
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Pattern Matching
|
|
82
|
+
```bash
|
|
83
|
+
# Match lines containing pattern
|
|
84
|
+
awk '/pattern/ {print}' file.txt
|
|
85
|
+
awk '/error/ {print $0}' logfile.txt
|
|
86
|
+
|
|
87
|
+
# Case-insensitive match
|
|
88
|
+
awk 'tolower($0) ~ /pattern/' file.txt
|
|
89
|
+
|
|
90
|
+
# Regex on specific field
|
|
91
|
+
awk '$2 ~ /pattern/' file.txt
|
|
92
|
+
awk '$2 !~ /pattern/' file.txt # Not matching
|
|
93
|
+
|
|
94
|
+
# Exact match
|
|
95
|
+
awk '$1 == "value"' file.txt
|
|
96
|
+
awk '$2 != "value"' file.txt
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Numeric Comparisons
|
|
100
|
+
```bash
|
|
101
|
+
# Greater than
|
|
102
|
+
awk '$3 > 100' file.txt
|
|
103
|
+
|
|
104
|
+
# Less than or equal
|
|
105
|
+
awk '$2 <= 50' file.txt
|
|
106
|
+
|
|
107
|
+
# Range
|
|
108
|
+
awk '$1 >= 10 && $1 <= 20' file.txt
|
|
109
|
+
|
|
110
|
+
# Complex conditions
|
|
111
|
+
awk '$1 > 100 && $2 == "active"' file.txt
|
|
112
|
+
awk '$1 > 100 || $2 > 200' file.txt
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### BEGIN and END Blocks
|
|
116
|
+
```bash
|
|
117
|
+
# Header and footer
|
|
118
|
+
awk 'BEGIN {print "Name\tAge"} {print $1, $2} END {print "---"}' file
|
|
119
|
+
|
|
120
|
+
# Initialize variables
|
|
121
|
+
awk 'BEGIN {count=0} {count++} END {print count}' file
|
|
122
|
+
|
|
123
|
+
# Set field separator in BEGIN
|
|
124
|
+
awk 'BEGIN {FS=","} {print $1}' file.csv
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Calculations
|
|
128
|
+
```bash
|
|
129
|
+
# Sum a column
|
|
130
|
+
awk '{sum += $1} END {print sum}' file.txt
|
|
131
|
+
|
|
132
|
+
# Average
|
|
133
|
+
awk '{sum += $1; count++} END {print sum/count}' file
|
|
134
|
+
|
|
135
|
+
# Count records
|
|
136
|
+
awk 'END {print NR}' file.txt
|
|
137
|
+
|
|
138
|
+
# Max value
|
|
139
|
+
awk 'BEGIN {max=0} {if ($1 > max) max=$1} END {print max}' file
|
|
140
|
+
|
|
141
|
+
# Count occurrences
|
|
142
|
+
awk '{count[$1]++} END {for (key in count) print key, count[key]}' file
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Conditional Processing
|
|
146
|
+
```bash
|
|
147
|
+
# If-else
|
|
148
|
+
awk '{if ($1 > 100) print "High"; else print "Low"}' file
|
|
149
|
+
|
|
150
|
+
# Ternary operator
|
|
151
|
+
awk '{print ($1 > 100) ? "High" : "Low"}' file
|
|
152
|
+
|
|
153
|
+
# Multiple conditions
|
|
154
|
+
awk '{
|
|
155
|
+
if ($1 > 100) print "High"
|
|
156
|
+
else if ($1 > 50) print "Medium"
|
|
157
|
+
else print "Low"
|
|
158
|
+
}' file
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Arrays
|
|
162
|
+
|
|
163
|
+
### Associative Arrays
|
|
164
|
+
```awk
|
|
165
|
+
# Count occurrences
|
|
166
|
+
awk '{count[$1]++} END {for (key in count) print key, count[key]}' file
|
|
167
|
+
|
|
168
|
+
# Group by key
|
|
169
|
+
awk '{sum[$1] += $2} END {for (key in sum) print key, sum[key]}' file
|
|
170
|
+
|
|
171
|
+
# Check if key exists
|
|
172
|
+
awk '{if ($1 in array) print "Duplicate"}' file
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Array Examples
|
|
176
|
+
```bash
|
|
177
|
+
# Count unique values
|
|
178
|
+
awk '{a[$1]++} END {print length(a)}' file
|
|
179
|
+
|
|
180
|
+
# Find duplicates
|
|
181
|
+
awk '{count[$1]++} END {for (k in count) if (count[k] > 1) print k}' file
|
|
182
|
+
|
|
183
|
+
# Store and print in order
|
|
184
|
+
awk '{lines[NR] = $0} END {for (i=1; i<=NR; i++) print lines[i]}' file
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Functions
|
|
188
|
+
|
|
189
|
+
### Built-in String Functions
|
|
190
|
+
```awk
|
|
191
|
+
length(string) # String length
|
|
192
|
+
substr(string, start, len) # Substring
|
|
193
|
+
index(string, substring) # Find substring position
|
|
194
|
+
split(string, array, sep) # Split string into array
|
|
195
|
+
sub(regex, replacement, string) # Replace first match
|
|
196
|
+
gsub(regex, replacement, string) # Replace all matches
|
|
197
|
+
tolower(string) # Convert to lowercase
|
|
198
|
+
toupper(string) # Convert to uppercase
|
|
199
|
+
match(string, regex) # Test regex match
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### String Function Examples
|
|
203
|
+
```bash
|
|
204
|
+
# String length
|
|
205
|
+
awk '{print length($1)}' file
|
|
206
|
+
|
|
207
|
+
# Substring
|
|
208
|
+
awk '{print substr($1, 1, 3)}' file # First 3 characters
|
|
209
|
+
|
|
210
|
+
# Replace
|
|
211
|
+
awk '{gsub(/old/, "new"); print}' file
|
|
212
|
+
|
|
213
|
+
# Convert case
|
|
214
|
+
awk '{print toupper($1)}' file
|
|
215
|
+
|
|
216
|
+
# Split and process
|
|
217
|
+
awk '{split($0, a, ":"); print a[1]}' /etc/passwd
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Math Functions
|
|
221
|
+
```awk
|
|
222
|
+
int(x) # Integer part
|
|
223
|
+
sqrt(x) # Square root
|
|
224
|
+
sin(x) # Sine
|
|
225
|
+
cos(x) # Cosine
|
|
226
|
+
atan2(y,x) # Arctangent
|
|
227
|
+
log(x) # Natural logarithm
|
|
228
|
+
exp(x) # Exponential
|
|
229
|
+
rand() # Random number [0,1)
|
|
230
|
+
srand() # Seed random number generator
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Practical Examples for Shell Scripts
|
|
234
|
+
|
|
235
|
+
### Log File Analysis
|
|
236
|
+
```bash
|
|
237
|
+
# Count HTTP status codes
|
|
238
|
+
awk '{print $9}' access.log | sort | uniq -c
|
|
239
|
+
|
|
240
|
+
# Sum response times
|
|
241
|
+
awk '{sum += $10; count++} END {print sum/count}' access.log
|
|
242
|
+
|
|
243
|
+
# Filter by time range
|
|
244
|
+
awk '$4 > "[01/Jan/2025:10:00:00" && $4 < "[01/Jan/2025:11:00:00"' access.log
|
|
245
|
+
|
|
246
|
+
# Extract and count IPs
|
|
247
|
+
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### CSV Processing
|
|
251
|
+
```bash
|
|
252
|
+
# Print specific columns from CSV
|
|
253
|
+
awk -F',' '{print $1, $3}' file.csv
|
|
254
|
+
|
|
255
|
+
# Skip header
|
|
256
|
+
awk -F',' 'NR > 1 {print $1, $2}' file.csv
|
|
257
|
+
|
|
258
|
+
# Convert CSV to tab-separated
|
|
259
|
+
awk -F',' -v OFS='\t' '{print $1, $2, $3}' file.csv
|
|
260
|
+
|
|
261
|
+
# Filter rows
|
|
262
|
+
awk -F',' '$3 > 100 {print $0}' file.csv
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### System Administration
|
|
266
|
+
```bash
|
|
267
|
+
# Parse /etc/passwd
|
|
268
|
+
awk -F':' '{print $1, $6}' /etc/passwd # username, home directory
|
|
269
|
+
awk -F':' '$3 >= 1000 {print $1}' /etc/passwd # Regular users
|
|
270
|
+
|
|
271
|
+
# Disk usage analysis
|
|
272
|
+
df -h | awk '$5 > 80 {print $0}' # > 80% full
|
|
273
|
+
|
|
274
|
+
# Process monitoring
|
|
275
|
+
ps aux | awk '$3 > 50 {print $2, $11}' # High CPU processes
|
|
276
|
+
|
|
277
|
+
# Network stats
|
|
278
|
+
netstat -an | awk '/ESTABLISHED/ {print $5}' | cut -d: -f1 | sort | uniq -c
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Data Transformation
|
|
282
|
+
```bash
|
|
283
|
+
# Swap columns
|
|
284
|
+
awk '{print $2, $1}' file
|
|
285
|
+
|
|
286
|
+
# Add line numbers
|
|
287
|
+
awk '{print NR ":", $0}' file
|
|
288
|
+
|
|
289
|
+
# Remove duplicates (keeping first occurrence)
|
|
290
|
+
awk '!seen[$0]++' file
|
|
291
|
+
|
|
292
|
+
# Join lines
|
|
293
|
+
awk '{printf "%s ", $0} END {print ""}' file
|
|
294
|
+
|
|
295
|
+
# Transpose rows to columns
|
|
296
|
+
awk '{for (i=1; i<=NF; i++) a[NR,i]=$i; max=(NF>max?NF:max)}
|
|
297
|
+
END {for (i=1; i<=max; i++) {
|
|
298
|
+
for (j=1; j<=NR; j++) printf "%s ", a[j,i]
|
|
299
|
+
print ""
|
|
300
|
+
}}' file
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Multi-line AWK Scripts
|
|
304
|
+
|
|
305
|
+
### In Shell Script
|
|
306
|
+
```bash
|
|
307
|
+
awk '
|
|
308
|
+
BEGIN {
|
|
309
|
+
FS = ","
|
|
310
|
+
print "Processing..."
|
|
311
|
+
}
|
|
312
|
+
{
|
|
313
|
+
sum += $2
|
|
314
|
+
count++
|
|
315
|
+
}
|
|
316
|
+
END {
|
|
317
|
+
print "Average:", sum/count
|
|
318
|
+
}
|
|
319
|
+
' file.csv
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### External AWK File
|
|
323
|
+
```bash
|
|
324
|
+
# script.awk
|
|
325
|
+
BEGIN {
|
|
326
|
+
FS = ","
|
|
327
|
+
}
|
|
328
|
+
{
|
|
329
|
+
sum += $2
|
|
330
|
+
}
|
|
331
|
+
END {
|
|
332
|
+
print "Total:", sum
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
# Execute
|
|
336
|
+
awk -f script.awk file.csv
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Common Patterns
|
|
340
|
+
|
|
341
|
+
### Skip Empty Lines
|
|
342
|
+
```bash
|
|
343
|
+
awk 'NF > 0' file
|
|
344
|
+
awk '/./' file
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Print Line Range
|
|
348
|
+
```bash
|
|
349
|
+
awk 'NR>=10 && NR<=20' file # Lines 10-20
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Print Unique Lines
|
|
353
|
+
```bash
|
|
354
|
+
awk '!seen[$0]++' file
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Count Pattern Occurrences
|
|
358
|
+
```bash
|
|
359
|
+
awk '/pattern/ {count++} END {print count}' file
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Format Output
|
|
363
|
+
```bash
|
|
364
|
+
# Fixed-width columns
|
|
365
|
+
awk '{printf "%-20s %10s\n", $1, $2}' file
|
|
366
|
+
|
|
367
|
+
# Align numbers
|
|
368
|
+
awk '{printf "%s: %8.2f\n", $1, $2}' file
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Performance Tips
|
|
372
|
+
|
|
373
|
+
### 1. Use Built-in Variables
|
|
374
|
+
```bash
|
|
375
|
+
# Faster
|
|
376
|
+
awk '{print $NF}' file
|
|
377
|
+
|
|
378
|
+
# Slower
|
|
379
|
+
awk '{print $length($0)}' file
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### 2. Avoid Unnecessary Operations
|
|
383
|
+
```bash
|
|
384
|
+
# Good
|
|
385
|
+
awk '$1 > 100' file
|
|
386
|
+
|
|
387
|
+
# Wasteful
|
|
388
|
+
awk '{if ($1 > 100) print $0}' file
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### 3. Use Regex Efficiently
|
|
392
|
+
```bash
|
|
393
|
+
# Compile regex once
|
|
394
|
+
awk 'BEGIN {pattern = /error/} $0 ~ pattern' file
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## Common Pitfalls in Shell Scripts
|
|
398
|
+
|
|
399
|
+
### 1. Not Quoting AWK Scripts
|
|
400
|
+
```bash
|
|
401
|
+
# Wrong - shell expands $1
|
|
402
|
+
awk {print $1} file
|
|
403
|
+
|
|
404
|
+
# Right
|
|
405
|
+
awk '{print $1}' file
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### 2. Division by Zero
|
|
409
|
+
```bash
|
|
410
|
+
# Dangerous
|
|
411
|
+
awk '{print $1/$2}' file
|
|
412
|
+
|
|
413
|
+
# Safe
|
|
414
|
+
awk '{if ($2 != 0) print $1/$2; else print "N/A"}' file
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### 3. Floating Point Comparison
|
|
418
|
+
```bash
|
|
419
|
+
# Problematic
|
|
420
|
+
awk '$1 == 0.1' file
|
|
421
|
+
|
|
422
|
+
# Better
|
|
423
|
+
awk 'function abs(x){return x<0?-x:x} abs($1 - 0.1) < 0.001' file
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### 4. Not Handling Missing Fields
|
|
427
|
+
```bash
|
|
428
|
+
# Check field existence
|
|
429
|
+
awk 'NF >= 3 {print $3}' file
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Combining with Other Tools
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
# awk with grep
|
|
436
|
+
grep "error" log | awk '{print $1, $NF}'
|
|
437
|
+
|
|
438
|
+
# awk with sort
|
|
439
|
+
awk '{print $2}' file | sort -n
|
|
440
|
+
|
|
441
|
+
# Pipeline
|
|
442
|
+
cat file | awk '$1 > 100' | sort | uniq
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
## Resources
|
|
446
|
+
|
|
447
|
+
- [GNU AWK Manual](https://www.gnu.org/software/gawk/manual/)
|
|
448
|
+
- [AWK Programming Language](https://www.amazon.com/AWK-Programming-Language-Alfred-Aho/dp/020107981X)
|
|
449
|
+
- [gawk(1) Man Page](https://man7.org/linux/man-pages/man1/gawk.1.html)
|