Difference between revisions of "bash/globbing"
(2 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
This actively interferes with the ability of programs such as [[grep/file masks|grep]] to behave intuitively when given a file-mask spec as input for processing, because: | This actively interferes with the ability of programs such as [[grep/file masks|grep]] to behave intuitively when given a file-mask spec as input for processing, because: | ||
===wildcard obfuscation=== | ===wildcard obfuscation=== | ||
− | * any mask entered will apply only to the current folder. | + | * any mask entered will apply only to the current folder -- not subfolders or anything under them. |
− | * folders are only included if their names ''also'' match the mask | + | * folders (within the current folder) are only included if their names ''also'' match the mask |
− | ** ...thus not being useful as far as | + | ** ...thus not being useful as far as filtering recursively; the program will have to get its own directory listings for that. |
+ | * applications are actively prevented from using wildcards in other ways that might be more intuitive in context, e.g. | ||
+ | ** a package-manager might allow you to list (or act on) packages whose names match a glob | ||
+ | ** a file-utility might want a glob to refer to the names of files being acted on, as a means of defining the *output* name | ||
+ | *** Examples: | ||
+ | **** <syntaxhighlight inline lang="Bash">copy *.png *.backup.*</syntaxhighlight> could mean "copy all .PNG files to this same folder but add ".backup" before the ".png" | ||
+ | ***** NOTE: DOS utilities often made use of this convention. | ||
+ | **** <syntaxhighlight inline lang="Bash">move ????????.png ????/*.*</syntaxhighlight>" could mean, where the files all begin with a YYYYMMDD date, "move all of these files into a folder whose name is the year given in the filename" | ||
+ | |||
===inconsistency=== | ===inconsistency=== | ||
Apparently the file-mask will be passed literally ''if'' no matches are found. (I guess this is useful so the program can say "no matches found for {{arg|filemask}}", but...) | Apparently the file-mask will be passed literally ''if'' no matches are found. (I guess this is useful so the program can say "no matches found for {{arg|filemask}}", but...) | ||
===ambiguity=== | ===ambiguity=== | ||
If there is a file whose name looks like an option because it begins with "-" or "--", and that file matches the file-mask given, the auto-globbing feature will include it verbatim in such a way that the executable may not be able to tell whether it's part of a file-listing or is actually an option from the command-line. | If there is a file whose name looks like an option because it begins with "-" or "--", and that file matches the file-mask given, the auto-globbing feature will include it verbatim in such a way that the executable may not be able to tell whether it's part of a file-listing or is actually an option from the command-line. | ||
+ | |||
==Workarounds== | ==Workarounds== | ||
Globbing can be turned off on a per-session basis: | Globbing can be turned off on a per-session basis: | ||
Line 21: | Line 30: | ||
* <code>help set</code> | * <code>help set</code> | ||
*: returns more information about bash's <code>set</code> command (the "set" manpage is for something else) | *: returns more information about bash's <code>set</code> command (the "set" manpage is for something else) | ||
− | + | ||
− | + | Explicitly enclosing the filemask in quotes (double or single) suppresses auto-globbing. <code>bash</code> will strip off the quotes but not parse the contents. | |
+ | * The same is true for backslash-escaping the "*" character, as in <code>\*.log</code> | ||
+ | |||
+ | Untested: | ||
+ | * <syntaxhighlight inline lang="Bash">ls -1 | grep </syntaxhighlight>{{arg|glob expression}}<syntaxhighlight inline lang="Bash"> | xargs rm </syntaxhighlight> | ||
==Related== | ==Related== |
Latest revision as of 18:57, 23 October 2024
The following notes may apply to other shell environments besides bash, but have only been tested with bash.
Commands invoked via bash always, by default, have each of their arguments parsed via the glob system facility before being passed to the command.
Problems
This actively interferes with the ability of programs such as grep to behave intuitively when given a file-mask spec as input for processing, because:
wildcard obfuscation
- any mask entered will apply only to the current folder -- not subfolders or anything under them.
- folders (within the current folder) are only included if their names also match the mask
- ...thus not being useful as far as filtering recursively; the program will have to get its own directory listings for that.
- applications are actively prevented from using wildcards in other ways that might be more intuitive in context, e.g.
- a package-manager might allow you to list (or act on) packages whose names match a glob
- a file-utility might want a glob to refer to the names of files being acted on, as a means of defining the *output* name
- Examples:
copy *.png *.backup.*
could mean "copy all .PNG files to this same folder but add ".backup" before the ".png"- NOTE: DOS utilities often made use of this convention.
move ????????.png ????/*.*
" could mean, where the files all begin with a YYYYMMDD date, "move all of these files into a folder whose name is the year given in the filename"
- Examples:
inconsistency
Apparently the file-mask will be passed literally if no matches are found. (I guess this is useful so the program can say "no matches found for <filemask>", but...)
ambiguity
If there is a file whose name looks like an option because it begins with "-" or "--", and that file matches the file-mask given, the auto-globbing feature will include it verbatim in such a way that the executable may not be able to tell whether it's part of a file-listing or is actually an option from the command-line.
Workarounds
Globbing can be turned off on a per-session basis:
set -o noglob
- turns off globbing
- put it in
~/.bashrc
to make it the default
set +o noglob
- turns globbing back on
help set
- returns more information about bash's
set
command (the "set" manpage is for something else)
- returns more information about bash's
Explicitly enclosing the filemask in quotes (double or single) suppresses auto-globbing. bash
will strip off the quotes but not parse the contents.
- The same is true for backslash-escaping the "*" character, as in
\*.log
Untested:
ls -1 | grep
<glob expression>| xargs rm
Related
- grep/file masks
- PHP/file/glob: globbing functions in PHP