Unix wildcard selectors? (Asterisks) - unix

In Ryan Bates' Railscast about git, his .gitignore file contains the following line:
tmp/**/*
What is the purpose of using the double asterisks followed by an asterisk as such: **/*?
Would using simply tmp/* instead of tmp/**/* not achieve the exact same result?
Googling the issue, I found an unclear IBM article about it, and I was wondering if someone could clarify the issue.

It says to go into all the subdirectories below tmp, as well as just the content of tmp.
e.g. I have the following:
$ find tmp
tmp
tmp/a
tmp/a/b
tmp/a/b/file1
tmp/b
tmp/b/c
tmp/b/c/file2
matched output:
$ echo tmp/*
tmp/a tmp/b
matched output:
$ echo tmp/**/*
tmp/a tmp/a/b tmp/a/b/file1 tmp/b tmp/b/c tmp/b/c/file2
It is a default feature of zsh, to get it to work in bash 4, you perform:
shopt -s globstar

From http://blog.privateergroup.com/2010/03/gitignore-file-for-android-development/:
(kwoods)
"The double asterisk (**) is not a git thing per say, it’s really a linux / Mac shell thing.
It would match on everything including any sub folders that had been created.
You can see the effect in the shell like so:
# ls ./tmp/* = should show you the contents of ./tmp (files and folders)
# ls ./tmp/** = same as above, but it would also go into each sub-folder and show the contents there as well."

According to the documentation of gitignore, this syntax is supported since git version 1.8.2.
Here is the relevant section:
Two consecutive asterisks (**) in patterns matched against full pathname may have special meaning:
A leading ** followed by a slash means match in all directories. For example, **/foo matches file or directory foo anywhere, the
same as pattern foo. **/foo/bar matches file or directory bar
anywhere that is directly under directory foo.
A trailing /** matches everything inside. For example, abc/** matches all files inside directory abc, relative to the location of
the .gitignore file, with infinite depth.
A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, a/**/b matches a/b,
a/x/b, a/x/y/b and so on.
Other consecutive asterisks are considered invalid.

Related

Zsh glob: Get everything except stuff in a certin folder

Trying to find all files except those inside vendor/ folders, but why is this failing?
setopt extendedglob
for file in **/*~vendor/; do
done
See if this does what you're looking for:
setopt extendedglob
print -l ^vendor/**/*(.)
The *~ negation syntax usually needs parentheses in order to determine where the expression after the tilde ends. Your pattern is requesting all files and folders except those where the glob result name ends with vendor/. The glob result never includes the trailing slash, so you end up with all of the files and folders.
Adding parens will change the behavior of that pattern, but probably not in a useful way. This will result in a list of all of the directories where the last component is not vendor:
print -l **/(*~vendor)/
so x/y, x/y/vendor/z, and vendor/a will be included, but x/y/vendor will not.
The parentheses limit the 'not' pattern to just one piece of the path. In order to exclude matches at the top-level, the tested component needs to be at the front of the pattern:
print -l (*~vendor)/**/*
The very first pattern above uses the ^ syntax to produce the same results. The (.) glob qualifier in that pattern limits the globbing to plain files, so directories are not included.
Another variation that may be useful - this will exclude directories that have any component named vendor. It is similar to find -prune:
print -l (^vendor/)#*(.)
This will produce a list of all files except those in subdirectories with names like vendor/x, a/vendor and a/vendor/b.

What does the "-Np1" option for the patch command do?

Someone sent me a patch and told me to apply it using the command:
patch -Np1 -i file.patch
Out of curiosity, I tried to find out what the -Np1 option does but the patch man page is curiously opaque on this. Can anyone explain what this does? Thanks.
It's two flags. -N and -p1.
-N or --forward
Ignore patches that seem to be reversed or already applied. See
also -R.
and
-pnum or --strip=num
Strip the smallest prefix containing num leading slashes from each
file name found in the patch file. A sequence of one or more adja-
cent slashes is counted as a single slash. This controls how file
names found in the patch file are treated, in case you keep your
files in a different directory than the person who sent out the
patch. For example, supposing the file name in the patch file was
/u/howard/src/blurfl/blurfl.c
setting -p0 gives the entire file name unmodified, -p1 gives
u/howard/src/blurfl/blurfl.c
without the leading slash, -p4 gives
blurfl/blurfl.c
and not specifying -p at all just gives you blurfl.c. Whatever you
end up with is looked for either in the current directory, or the
directory specified by the -d option.

rsync - Why is there an --include-from and an --exclude-from option?

The rsync man page says that...
--include-from=FILE: "specifies a FILE that contains include patterns.."
Likewise that...
--exclude-from=FILE: "specifies a FILE that contains exclude patterns.."
But I have also read examples on the internet where the same FILE can contain both patterns to include (if preceded by a +) and patterns to exclude (if preceded by a -)
Example:
+ testfile.txt
- testfile*
I know that order is important so here, if testfile.txt is matched then it will be copied to a destination dir but testfile[anything else] will not be copied.
If FILE can contain patterns to include and to exclude then why does rsync have both options --include-from=FILE and --exclude-from=FILE? It seems to me they both do the same thing. It's the order of matches (preceded by a + or a -) that determines if the file is copied or not.
Can someone give me an example of why you would use the --include-from option instead of the --exclude-from option? Can they both be used together? How would you?
Cheers,
Flex

How to make the glob() function also match hidden dot files in Vim?

In a Linux or Mac environment, Vim’s glob() function doesn’t match dot files such as .vimrc or .hiddenfile. Is there a way to get it to match all files including hidden ones?
The command I’m using:
let s:BackupFiles = glob("~/.vimbackup/*")
I’ve even tried setting the mysterious {flag} parameter to 1, and yet it still doesn’t return the hidden files.
Update: Thanks ib! Here’s the result of what I’ve been working on: delete-old-backups.vim.
That is due to how the glob() function works: A single-star pattern
does not match hidden files by design. In most shells, the default
globbing style can be changed to do so (e.g., via shopt -s dotglob
in Bash), but it is not possible in Vim, unfortunately.
However, one has several possibilities to solve the problem still.
First and most obvious is to glob hidden and not hidden files
separately and then concatenate the results:
:let backupfiles = glob(&backupdir..'/*').."\n"..glob(&backupdir..'/.[^.]*')
(Be careful not to fetch the . and .. entries along with hidden files.)
Another, perhaps more convenient but less portable way is to use
the backtick expansion within the glob() call:
:let backupfiles = glob('`find '..&backupdir..' -maxdepth 1 -type f`')
This forces Vim to execute the command inside backticks to obtain
the list of files. The find shell command lists all files (-type f)
including the hidden ones, in the specified directory (-maxdepth 1
forbids recursion).

To restrict a node from `tree` by Tree or Git

How can you restrict a node from the command tree?
#1
I need to give a tree of my project files reqularly for my supervisor.
These files contain some third-party components which I do not want to show in the tree.
I have solved this problem this far by coping the project file to tmp, removing 3rd party-files and then running tree.
However, this procedure is becoming cumbersome.
I would like to get a better way to give tree of my files to my supervisor.
#2
I have the files which I want to show in Git so Git may solve this problem.
I run unsuccessfully
git ls-files --with-tree
You can specify the files you want to match and avoid using general patterns. From the tree manpage:
-P pattern
List only those files that match the wild-card pattern. Note: you must use the -a option to also consider those files beginning with a dot '.' for matching. Valid wildcard operators are '*' (any zero or more characters), '?' (any single character), '[...]' (any single character listed between brackets (optional - (dash) for character range may be used: ex: [A-Z]), and '[^...]' (any single character not listed in brackets) and '|' separates alternate patterns.
-I pattern
Do not list those files that match the wild-card pattern.
In your specific case, running
tree -I '3rd*'
should hide a directory called '3rd_party', including subdirs and files, while still allowing matches like 'party_3rd'. Obviously, other files and directories not containing '3rd' in the name will also display as normal. I've verified this behaviour with tree v1.5.2.1 on Linux.
You can put the third party tools is a separate subdirectory.
Then you only have to eliminate one node.
Instead of changing the tree command it might be better to place the 3rd-party files in a sibling folder of, not in a child folder of, your own source.

Resources