Search for *.swo
I think this should be an easy one, but it's got me stumped.
When I use the following, it finds the file.
$ ls -al .bash_*.sw*
-rw-r--r-- 1 damiensawyer staff 12288 27 Nov 07:39 .bash_profile.swo
But when I use this, it doesn't find it.
$ ls -al *.sw*
ls: *.sw*: No such file or directory
I expected the second command to also return .bash_profile.swo
. What am I missing?
Solution 1:
Using ls
The problem is that your file has two dots, not one. You need to account for that:
ls -al .*.sw*
This will match any file that begins with a dot (invisible files like .DS_Store
) and also ends with .sw*
.
.swa
as well as .swz
will match.
Using find
You can use the following to find all files with the same extension (swo
in the case below) in a directory.
find ~ -iname *swo
-iname
finds a case insensitive match.
You can search for that/those specific file(s) using this:
find .bash_*.sw*
Note: Using ~
as the path will search your entire home directory.
Solution 2:
This is not actually caused by ls
, since ls
never expands patterns.
The decision about how to expand glob patterns (patterns containing *
and ?
) is made by the shell. Your shell is most likely bash
.
By default bash
does not perform path expansion on dotfiles. However, it can do so either by explicitly writing the .
(as you discovered already) or by turning on the dotglob
option. From the bash manpage:
dotglob If set, bash includes filenames beginning with a `.' in the results of pathname expansion.
To demonstrate, let's just print the expansion with echo
instead of ls
:
$ touch .bash_profile.swo
$ echo .*.swo
.bash_profile.swo
$ echo *.swo
*.swo
$ shopt -s dotglob
$ echo *.swo
.bash_profile.swo
Futher discussion can be found here.
Solution 3:
The issue is that ls
only shows files that begin with a .
you have to explicitly have the first .
in the file glob.
Thus the following will work:
ls .*swo
Unix shells expand the glob before ls
sees the file names.
Solution 4:
These patterns (*.sw*
and the like) are known as globs.
As @Mark and @Zach Gates have noted, globs do not match files whose names begin with a period unless you explicitly include a .
at the beginning of the pattern. This is because in UNIX-like systems (such as OS X), files that begin with a dot are considered 'hidden' files and are generally not shown by default.
Glob matching is actually done by your shell (bash
by default), not by individual commands such as ls
.
As the bash manual explains under Filename Expansion:
After word splitting... Bash scans each word for the characters ‘
*
’, ‘?
’, and ‘[
’. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern (see Pattern Matching). If no matching filenames are found,...the word is left unchanged.When a pattern is used for filename expansion, the character ‘
.
’ at the start of a filename or immediately following a slash must be matched explicitly, unless the shell optiondotglob
is set.