Difference between revisions of "grep/file masks"

from HTYP, the free directory anyone can edit if they can prove to me that they're not a spambot
Jump to navigation Jump to search
Line 1: Line 1:
 
==About==
 
==About==
[[grep]] does not effectively support recursive searching with anything but a wide-open file mask ("*"). In other words, e.g. {{fmt/code|grep -r [text_to_find] *.log}} will not (in most contexts, including those where it's most likely to be used e.g. searching inside {{fmt/code|/var/log}}, because it will skip folders that don't ''also'' match the filemask -- i.e. it will only search in folders that end in {{fmt/code|.log}}.
+
If ''file'' is specified using wildcards (e.g. {{fmt/code|*.log}} or {{fmt/code|*}}), [[bash]] (the default command-line parser) [[bash/globbing|expands this into a listing of all matching files]] before passing it to grep. This interferes with [[grep]]'s ability to search multiple files. It can be overridden with quotes or escapes, but grep does not seem to have any wildcard-processing ability of its own (though grep ''must'' do some when it's doing recursion; to be investigated) -- so any wildcards passed through ''without'' expansion are seen by grep as names of files that don't exist.
  
This is because grep does not do its own file-filtering but relies entirely on the [[command line]] environment to translate file-mask specifications into a list of files, which are then each passed to grep as a separate argument. [[bash/globbing|This is a feature/defect of <code>bash</code>]] and possibly most other Linux [[command shell]]s (investigation needed).
+
'''Example''': {{fmt/code|grep -r [text_to_find] *.log}} will not (in most contexts, including those where it's most likely to be used e.g. searching inside {{fmt/code|/var/log}}, because it will skip folders that don't ''also'' match the filemask -- i.e. it will only search in folders that end in {{fmt/code|.log}}.
 +
 
 +
'''Example''': If the file-mask finds too many matches in the current folder, it can generate the error {{fmt/quote|bash: /bin/grep: Argument list too long}} -- even if the number of files ''with matching contents'' is zero or quite short.
  
 
In short, grep does not have the ability to search recursively using a file-mask, and any mask entered:
 
In short, grep does not have the ability to search recursively using a file-mask, and any mask entered:
* will apply only to the current folder
+
* will prevent grep from recursively searching any folders whose names do not also match (so, typically will only apply to the current/top folder)
* will prevent grep from recursively searching any folders whose names do not also match
+
* may prevent grep from being able to work at all if too many files in the top folder have names that match the wildcard pattern
 +
 
 +
See [[bash/globbing]] for more discussion.
 
==Links==
 
==Links==
 
* '''2020-02-04''' [https://toot.cat/@woozle/103602468124365262 #softwareGripe #grep #counterintuitive]
 
* '''2020-02-04''' [https://toot.cat/@woozle/103602468124365262 #softwareGripe #grep #counterintuitive]

Revision as of 15:11, 21 June 2022

About

If file is specified using wildcards (e.g. «*.log» or «*»), bash (the default command-line parser) expands this into a listing of all matching files before passing it to grep. This interferes with grep's ability to search multiple files. It can be overridden with quotes or escapes, but grep does not seem to have any wildcard-processing ability of its own (though grep must do some when it's doing recursion; to be investigated) -- so any wildcards passed through without expansion are seen by grep as names of files that don't exist.

Example: «grep -r [text_to_find] *.log» will not (in most contexts, including those where it's most likely to be used e.g. searching inside «/var/log», because it will skip folders that don't also match the filemask -- i.e. it will only search in folders that end in «.log».

Example: If the file-mask finds too many matches in the current folder, it can generate the error «bash: /bin/grep: Argument list too long» -- even if the number of files with matching contents is zero or quite short.

In short, grep does not have the ability to search recursively using a file-mask, and any mask entered:

  • will prevent grep from recursively searching any folders whose names do not also match (so, typically will only apply to the current/top folder)
  • may prevent grep from being able to work at all if too many files in the top folder have names that match the wildcard pattern

See bash/globbing for more discussion.

Links