mirror of
https://github.com/flokoe/bash-hackers-wiki.git
synced 2024-11-25 07:43:42 +01:00
30 lines
55 KiB
HTML
30 lines
55 KiB
HTML
|
<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><link href=https://flokoe.github.io/bash-hackers-wiki/syntax/pattern/ rel=canonical><link href=../basicgrammar/ rel=prev><link href=../pe/ rel=next><link rel=icon href=../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.5.44"><title>Patterns and pattern matching - The Bash Hackers Wiki</title><link rel=stylesheet href=../../assets/stylesheets/main.0253249f.min.css><link rel=stylesheet href=../../assets/stylesheets/palette.06af60db.min.css><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback"><style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style><script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#patterns-and-pattern-matching class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <header class=md-header data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../.. title="The Bash Hackers Wiki" class="md-header__button md-logo" aria-label="The Bash Hackers Wiki" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> The Bash Hackers Wiki </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Patterns and pattern matching </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to dark mode" type=radio name=__palette id=__palette_0> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> <input class=md-option data-md-color-media data-md-color-scheme=slate data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to light mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_0 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=ma
|
||
|
</code></pre></div> <h2 id=pattern-matching-configuration>Pattern matching configuration<a class=headerlink href=#pattern-matching-configuration title="Permanent link">¶</a></h2> <h3 id=related-shell-options>Related shell options<a class=headerlink href=#related-shell-options title="Permanent link">¶</a></h3> <table> <thead> <tr> <th>option</th> <th>classification</th> <th>description</th> </tr> </thead> <tbody> <tr> <td><code>dotglob</code></td> <td><a href=../expansion/globs/ >globbing</a></td> <td>see <a href=/syntax/expansion/globs.md#Customization>Pathname expansion customization</a></td> </tr> <tr> <td><code>extglob</code></td> <td>global</td> <td>enable/disable extended pattern matching language, as described above</td> </tr> <tr> <td><code>failglob</code></td> <td><a href=../expansion/globs/ >globbing</a></td> <td>see <a href=/syntax/expansion/globs.md#Customization>Pathname expansion customization</a></td> </tr> <tr> <td><code>nocaseglob</code></td> <td><a href=../expansion/globs/ >globbing</a></td> <td>see <a href=/syntax/expansion/globs.md#Customization>Pathname expansion customization</a></td> </tr> <tr> <td><code>nocasematch</code></td> <td>pattern/string matching</td> <td>perform pattern matching without regarding the case of individual letters</td> </tr> <tr> <td><code>nullglob</code></td> <td><a href=../expansion/globs/ >globbing</a></td> <td>see <a href=/syntax/expansion/globs.md#Customization>Pathname expansion customization</a></td> </tr> <tr> <td><code>globasciiranges</code></td> <td><a href=../expansion/globs/ >globbing</a></td> <td>see <a href=/syntax/expansion/globs.md#Customization>Pathname expansion customization</a></td> </tr> </tbody> </table> <h2 id=bugs-and-portability-considerations>Bugs and Portability considerations<a class=headerlink href=#bugs-and-portability-considerations title="Permanent link">¶</a></h2> <p>* Counter-intuitively, only the <code>[!chars]</code> syntax for negating a character class is specified by POSIX for shell pattern matching. <code>[^chars]</code> is merely a commonly-supported extension. Even dash supports <code>[^chars]</code>, but not posh.</p> <p>* All of the extglob quantifiers supported by bash were supported by ksh88. The set of extglob quantifiers supported by ksh88 are identical to those supported by Bash, mksh, ksh93, and zsh.</p> <p>* mksh does not support POSIX character classes. Therefore, character ranges like <code>[0-9]</code> are somewhat more portable than an equivalent POSIX class like <code>[:digit:]</code>.</p> <p>* Bash uses a custom runtime interpreter for pattern matching. (at least) ksh93 and zsh translate patterns into regexes and then use a regex compiler to emit and cache optimized pattern matching code. This means Bash may be an order of magnitude or more slower in cases that involve complex back-tracking (usually that means extglob quantifier nesting). You may wish to use Bash's regex support (the <code>=~</code> operator) if performance is a problem, because Bash will use your C library regex implementation rather than its own pattern matcher.</p> <p>TODO: describe the pattern escape bug <a href=https://gist.github.com/ormaaj/6195070>https://gist.github.com/ormaaj/6195070</a></p> <h3 id=ksh93-extras>ksh93 extras<a class=headerlink href=#ksh93-extras title="Permanent link">¶</a></h3> <p>ksh93 supports some very powerful pattern matching features in addition to those described above.</p> <p>* ksh93 supports arbitrary quantifiers just like ERE using the <code>{from,to}(pattern-list)</code> syntax. <code>{2,4}(foo)bar</code> matches between 2-4 "foo"'s followed by "bar". <code>{2,}(foo)bar</code> matches 2 or more "foo"'s followed by "bar". You can probably figure out the rest. So far, none of the other shells support this syntax.</p> <p>* In ksh93, a <code>pattern-list</code> may be delimited by either <code>&</code> or <code>|</code>. <code>&</code> means "all patterns must be matched" instead of "any pattern". For example, <code>[[ fo0bar == @(fo[0-9]&+([[:alnum:]]))bar ]]</code> would be true while <c
|
||
|
</script> <script>
|
||
|
var giscus = document.querySelector("script[src*=giscus]")
|
||
|
|
||
|
/* Set palette on initial load */
|
||
|
var palette = __md_get("__palette")
|
||
|
if (palette && typeof palette.color === "object") {
|
||
|
var theme = palette.color.scheme === "slate" ? "dark" : "light"
|
||
|
giscus.setAttribute("data-theme", theme)
|
||
|
}
|
||
|
|
||
|
/* Register event handlers after documented loaded */
|
||
|
document.addEventListener("DOMContentLoaded", function() {
|
||
|
var ref = document.querySelector("[data-md-component=palette]")
|
||
|
ref.addEventListener("change", function() {
|
||
|
var palette = __md_get("__palette")
|
||
|
if (palette && typeof palette.color === "object") {
|
||
|
var theme = palette.color.scheme === "slate" ? "dark" : "light"
|
||
|
|
||
|
/* Instruct Giscus to change theme */
|
||
|
var frame = document.querySelector(".giscus-frame")
|
||
|
frame.contentWindow.postMessage(
|
||
|
{ giscus: { setConfig: { theme } } },
|
||
|
"https://giscus.app"
|
||
|
)
|
||
|
}
|
||
|
})
|
||
|
})
|
||
|
</script> </article> </div> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class=md-footer> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class=md-copyright> Made with <a href=https://squidfunk.github.io/mkdocs-material/ target=_blank rel=noopener> Material for MkDocs </a> </div> </div> </div> </footer> </div> <div class=md-dialog data-md-component=dialog> <div class="md-dialog__inner md-typeset"></div> </div> <script id=__config type=application/json>{"base": "../..", "features": ["navigation.instant", "navigation.tracking", "navigation.tabs", "navigation.sections", "navigation.top", "content.action.view", "content.action.edit", "search.suggest", "search.highlight", "content.code.copy"], "search": "../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script> <script src=../../assets/javascripts/bundle.83f73b43.min.js></script> </body> </html>
|