Skip to main content
typos, -prune for every dir, not just hidden ones.
Source Link
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense to make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so almost allmany Bourne/POSIX shells (sh, dash, bash, AT&T ksh, yash …) include them, as do (t)csh and even fish 1.x. A few shells excluydeexclude . and .. from all wildcard matches: zsh, pdksh/posh/mksh (unlike ATTAT&T ksh), fish ≥2.0.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -prune -name '.*' -exec chown -R username:groupname {} + -prune

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so almost all Bourne/POSIX shells (sh, dash, bash, ksh, …) include them, as do (t)csh and even fish 1.x. A few shells excluyde . and .. from all wildcard matches: zsh, pdksh/posh/mksh (unlike ATT ksh), fish ≥2.0.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -name '.*' -exec chown -R username:groupname {} + -prune

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense to make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so many Bourne/POSIX shells (sh, dash, bash, AT&T ksh, yash …) include them, as do (t)csh and even fish 1.x. A few shells exclude . and .. from all wildcard matches: zsh, pdksh/posh/mksh (unlike AT&T ksh), fish ≥2.0.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -prune -name '.*' -exec chown -R username:groupname {} +
pdksh and derivatives do exclude . and .. (thanks Stéphane Chazelas)
Source Link
Gilles 'SO- stop being evil'
  • 865.3k
  • 205
  • 1.8k
  • 2.3k

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so almost all Bourne/POSIX shells (sh, dash, bash, ksh, …) include them, as do (t)csh and even fish 1.x. Zsh defaults to excludingA few shells excluyde . and .. from all wildcard matches: zsh, as doespdksh/posh/mksh (unlike ATT ksh), fish fish ≥2≥2.0.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -name '.*' -exec chown -R username:groupname {} + -prune

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so Bourne/POSIX shells (sh, dash, bash, ksh, …) include them, as do (t)csh and even fish 1.x. Zsh defaults to excluding . and .. from wildcard matches, as does fish ≥2.0.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -name '.*' -exec chown -R username:groupname {} + -prune

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so almost all Bourne/POSIX shells (sh, dash, bash, ksh, …) include them, as do (t)csh and even fish 1.x. A few shells excluyde . and .. from all wildcard matches: zsh, pdksh/posh/mksh (unlike ATT ksh), fish ≥2.0.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -name '.*' -exec chown -R username:groupname {} + -prune
fish 2 has changed to exclude . and .. (thanks xfix)
Source Link
Gilles 'SO- stop being evil'
  • 865.3k
  • 205
  • 1.8k
  • 2.3k

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so Bourne/POSIX shells (sh, dash, bash, ksh, …) include them, as do (t)csh and even fish 1.x. Zsh alone among the common shells defaults to excluding . and .. from wildcard matches, as does fish ≥2.0.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -name '.*' -exec chown -R username:groupname {} + -prune

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so Bourne/POSIX shells (sh, dash, bash, ksh, …) include them, as do (t)csh and even fish. Zsh alone among the common shells defaults to excluding . and .. from wildcard matches.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -name '.*' -exec chown -R username:groupname {} + -prune

The character . is only excluded from wildcard matching when it's the first character of the file name and it would be matched by a wildcard. In the pattern .*, the * matches strings beginning with ., so .* includes .. (as well as ., with * matching the empty string). This is a straightforward consequence of the pattern matching rules, annoying though it may be.

It would make sense make an exception and to systematically exclude . and .. from matches, but that's not how it was done historically, so Bourne/POSIX shells (sh, dash, bash, ksh, …) include them, as do (t)csh and even fish 1.x. Zsh defaults to excluding . and .. from wildcard matches, as does fish ≥2.0.

If you set GLOBIGNORE to any non-empty value, bash switches to the convenient but non-standard behavior of excluding . and .. from matches. Setting GLOBIGNORE also turns off the behavior of excluding dot files; with GLOBIGNORE='.*', you get the usual behavior of ./* excluding dot files, but ./.* matches only dot files and not . or ... Set GLOBIGNORE=.:.. (or GLOBIGNORE=.) to have ./* match all files, including dot files, but excluding . and ...

In ksh93, set FIGNORE='@(.|..)' to exclude . and .. from matches but include dot files. Thus .* will expand to dot files but not include . or ...

Without resorting to shell-specific features, you can match dot files with the following two globs:

.[!.]* ..?*

and all files (excluding . and ..) with the following three globs:

..?* .[!.]* *

But you need to take care because one or several of the globs might not match any file, which would cause the corresponding pattern to remain unexpanded.

To avoid surprises, it might be easier to use find. find never recurses to the parent directory (unless told to follow symbolic links).

find /home/username/. -name . -o -name '.*' -exec chown -R username:groupname {} + -prune
Source Link
Gilles 'SO- stop being evil'
  • 865.3k
  • 205
  • 1.8k
  • 2.3k
Loading