A CLI tool for editing Vinyl VCL files.
Built for pipelines, config management, and anyone tired of fragile sed commands touching production VCL.
| Feature | Description |
|---|---|
| Formatting | Pretty-print VCL with consistent indentation and spacing via format. |
| Insertion | Inject VCL text at a structurally matched position via insert. |
| Find & Replace | Find and replace token patterns with wildcard and capture support via replace. |
| Extraction | Pattern-match against token streams and print matching regions or templated captures via extract. |
| Dry Run | Preview changes as a unified diff before applying with --dry-run. |
| Composable | Pipe commands together to chain multiple edits in one pass. |
| Token Debugging | Dump the token stream for debugging via tokens. |
| Native Lexing | Uses the actual Vinyl lexer (via libvcc) for structural awareness. |
Pretty-print a VCL file
vinyl-edit format default.vcl
# or pipe it and read from stdin
cat default.vcl | vinyl-edit format -Replace host and port values in first backend
cat default.vcl \
| vinyl-edit replace - '.host = **' '.host = "newhost.example.com"' --limit 1 \
| vinyl-edit replace - '.port = **' '.port = "8080"' --limit 1Append IP to all ACLs
vinyl-edit replace default.vcl 'acl ** {***}' 'acl **1 {**2 "10.0.0.1"/32;}'Remove an IP from an named ACL
vinyl-edit replace default.vcl 'acl purge { *** "10.0.0.1"/32; ***}' 'acl purge {**1**2}'Show all backend definitions
vinyl-edit extract default.vcl 'backend ** {***}'Extract all entries from ACLs (strip leading/trailing whitespace)
vinyl-edit extract default.vcl 'acl ** {***}' '**2' --strip-whitespacePatterns in vinyl-edit operate on tokens, not raw text. The VCL source is first parsed into a token stream using the native Vinyl lexer, and patterns are matched against that stream. This means whitespace and line breaks don't matter.
Note that the input VCL must be syntactically valid. The lexer will throw an error if it encounters unknown tokens. However, it does not check that the VCL is semantically correct. ".host=**" matches the same as ".host = **" because the lexer produces the same tokens either way. Patterns can span multiple lines without any special syntax.
Literal tokens in a pattern must match exactly. For example, the pattern sub vcl_recv { matches those three tokens in sequence regardless of how the original source is spaced or indented.
| Pattern | Matches |
|---|---|
** |
Exactly one token |
*** |
Zero or more tokens (non-greedy) |
Use ** when you know the structure but not the value, like .host = ** to match any single host value. Use *** to span unknown regions, like acl ** {***} to match an entire ACL body of any length.
Two special boundary tokens can be used to pin a pattern to the start or end of the file:
| Anchor | Position |
|---|---|
SOI |
Start of input |
EOI |
End of input |
For example, SOI vcl **; matches the VCL version declaration only if it appears at the very beginning of the file.
In replace and extract, wildcards become numbered capture groups in the order they appear. Reference them with **1, **2, etc.
For example, given the pattern acl ** {***}, **1 captures the ACL name and **2 captures the body. A replacement of acl **1 {**2 "10.0.0.1"/32;} preserves the original name and body while appending a new entry.
In extract, captures work the same way via the template argument. Running extract 'acl ** {***}' '**2' prints just the body of each ACL, discarding the surrounding structure.
macOS (ARM64):
brew tap null93/tap
brew install vinyl-editLinux (ARM64):
curl -sLo /usr/local/bin/vinyl-edit https://github.com/null93/vinyl-edit/releases/download/0.0.1/vinyl-edit_0.0.0_linux_arm64
chmod +x /usr/local/bin/vinyl-editLinux (AMD64):
curl -sLo /usr/local/bin/vinyl-edit https://github.com/null93/vinyl-edit/releases/download/0.0.1/vinyl-edit_0.0.0_linux_amd64
chmod +x /usr/local/bin/vinyl-editIn order to build the Vinyl Cache libraries, you will need to install the following dependencies:
macOS (Homebrew):
brew install autoconf automake docutils sphinx-doc libtool pkgconf pcre2Debian/Ubuntu:
apt install build-essential autoconf automake libtool pkg-config libpcre2-devYou can then build the vinyl-edit binary with:
make buildThe first build will automatically compile the vendored Vinyl lexer library. The binary lands in dist/vinyl-edit.
Project was built with TDD, so there are a few tests located in the test directory.
You can run them suite with:
make test