如何在 bash 中使用 .* 通配符但排除父目录 (..)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2910049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use the .* wildcard in bash but exclude the parent directory (..)?
提问by Allan
There are often times that I want to execute a command on all files (including hidden files) in a directory. When I try using
很多时候我想对一个目录中的所有文件(包括隐藏文件)执行一个命令。当我尝试使用
chmod g+w * .*
it changes the permissions on all the files I want (in the directory) and all the files in the parent directory (that I want left alone).
它更改了我想要的所有文件(在目录中)和父目录中的所有文件(我想单独留下)的权限。
Is there a wildcard that does the right thing or do I need to start using find?
是否有一个通配符可以做正确的事情,或者我需要开始使用 find 吗?
回答by Chris Johnsen
You will need two glob patterns to cover all the potential “dot files”: .[^.]*and ..?*.
您将需要两个 glob 模式来覆盖所有潜在的“点文件”:.[^.]*和..?*.
The first matches all directory entries with two or more characters where the first character is a dot and the second character is not a dot. The second picks up entries with three or more characters that start with ..(this excludes ..because it only has two characters and starts with a ., but includes (unlikely) entries like ..foo).
第一个匹配具有两个或多个字符的所有目录条目,其中第一个字符是点,第二个字符不是点。第二个选择以三个或更多字符开头的条目..(这不包括,..因为它只有两个字符并以 a 开头.,但包括(不太可能)这样的条目..foo)。
chmod g+w .[^.]* ..?*
This should work well in most all shells and is suitable for scripts.
这应该适用于大多数 shell,并且适用于脚本。
For regular interactive use, the patterns may be too difficult to remember. For those cases, your shell might have a more convenient way to skip .and ...
zshalways excludes .and ..from patterns like .*.
With bash, you have to use the GLOBIGNORE shell variable.
对于常规的交互使用,模式可能很难记住。对于这些情况,您的 shell 可能有更方便的方法来跳过.和..。
zsh总是排除.和排除..像.*. 使用bash,您必须使用 GLOBIGNORE shell 变量。
# bash
GLOBIGNORE=.:..
echo .*
You might consider setting GLOBIGNORE in one of your bashcustomization files (e.g. .bash_profile/.bash_loginor .bashrc).
Beware, however, becoming accustomed to this customization if you often use other environments.
If you run a command like chmod g+w .*in an environment that is missing your customization, then you will unexpectedly end up including .and ..in your command.
您可能会考虑在您的bash自定义文件之一(例如.bash_profile/.bash_login或.bashrc)中设置 GLOBIGNORE 。但是,如果您经常使用其他环境,请注意习惯这种自定义。如果您chmod g+w .*在缺少自定义的环境中运行命令,那么您最终会意外地将.和包含..在您的命令中。
Additionally, you can configure the shells to include “dot files” in patterns that do not start with an explicit dot (e.g. *).
此外,您可以将 shell 配置为在不以显式点(例如*)开头的模式中包含“点文件” 。
# zsh
setopt glob_dots
# bash
shopt -s dotglob
# show all files, even “dot files”
echo *
回答by paxdiablo
Usually I would just use . .[a-zA-Z0-9]*since my file names tend to follow certain rules, but that won't catch allpossible cases.
通常我只会使用,. .[a-zA-Z0-9]*因为我的文件名往往遵循某些规则,但这不会涵盖所有可能的情况。
You canuse:
您可以使用:
chmod g+w $(ls -1a | grep -v '^..$')
which will basically list all the files and directories, strip out the parent directory then process the rest. Beware of spaces in file names though, it'll treat them as separate files.
这将基本上列出所有文件和目录,去掉父目录,然后处理其余的。但是请注意文件名中的空格,它会将它们视为单独的文件。
Of course, if you just want to do files, you can use:
当然,如果你只是想做文件,可以使用:
find . -maxdepth 0 -type f -exec chmod g+w {} ';'
or, yet another solution, which should do all files and directories except the ..one:
或者,另一种解决方案,它应该处理除..一个之外的所有文件和目录:
for i in * .* ; do if [[ ${i} != ".." ]] ; then chmod g+w "$i"; fi done
but now you're getting into territory where scripts or aliases may be necessary.
但现在您正在进入可能需要脚本或别名的领域。
回答by honril
What i did was
我所做的是
tar --directory my_directory --file my_directory.tar --create `ls -A mydirectory/`
Works just fine the ls -A my_directoryexpands to everything in the directory except .and ... No wierd globs, and on a single line.
可以很好地ls -A my_directory扩展到目录中的所有内容,除了.和..。没有奇怪的球体,并且在一条线上。
ps: Perhaps someone will tell me why this is not a good idea. :p
ps:也许有人会告诉我为什么这不是一个好主意。:p
回答by frank
How about:
怎么样:
shopt -s dotglob
chmod g+w ./*
回答by ColinM
Since you may not want to set dotglob for the rest of your bash session you can set it for a single set of commands by running in a subprocess like so:
由于您可能不想为 bash 会话的其余部分设置 dotglob,您可以通过在子进程中运行来为一组命令设置它,如下所示:
$ (shopt -s dotglob; chmod g+w ./*)
回答by Mark Booth
If you are sure that two character hidden file names will never be used, then the simplest option is just be to do:
如果您确定永远不会使用两个字符的隐藏文件名,那么最简单的选择就是这样做:
chmod g+w * ...*

