如何在 bash 中使用 .* 通配符但排除父目录 (..)?
很多时候我想对目录中的所有文件(包括隐藏文件)执行命令。当我尝试使用
chmod g+w * .*
它时,它会更改我想要的所有文件(在目录中)和父目录中的所有文件(我想单独保留)的权限。
是否有一个通配符可以做正确的事情,或者我需要开始使用 find 吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您将需要两个 glob 模式来覆盖所有潜在的“点文件”:
.[^.]*
和..?*
。第一个匹配具有两个或多个字符的所有目录条目,其中第一个字符是点,第二个字符不是点。第二个选取包含三个或更多字符且以
..
开头的条目(这不包括..
,因为它只有两个字符并以.
开头。 code>,但包括(不太可能)像..foo
这样的条目)。这应该在大多数 shell 中都能很好地工作,并且适合脚本。
对于常规的交互使用,这些模式可能太难记住。对于这些情况,您的 shell 可能有更方便的方法来跳过
.
和..
。zsh 始终从
.*
等模式中排除.
和..
。对于 bash,您必须使用 GLOBIGNORE shell 变量。
您可以考虑在您的 bash 自定义文件之一中设置 GLOBIGNORE(例如
.bash_profile
/.bash_login
或.bashrc
)。但是,如果您经常使用其他环境,请注意,要习惯这种自定义。
如果您在缺少自定义的环境中运行像
chmod g+w .*
这样的命令,那么您将意外地最终包含.
和..< /code> 在你的命令中。
此外,您可以将 shell 配置为在不以显式点开头的模式中包含“点文件”(例如
*
)。You will need two glob patterns to cover all the potential “dot files”:
.[^.]*
and..?*
.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
).This should work well in most all shells and is suitable for scripts.
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..
.zsh always excludes
.
and..
from patterns like.*
.With bash, you have to use the GLOBIGNORE shell variable.
You might consider setting GLOBIGNORE in one of your bash customization files (e.g.
.bash_profile
/.bash_login
or.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.Additionally, you can configure the shells to include “dot files” in patterns that do not start with an explicit dot (e.g.
*
).我所做的
很好,
ls -A my_directory
扩展到目录中除.
和..
之外的所有内容。没有奇怪的球,并且在一行上。ps:也许有人会告诉我为什么这不是一个好主意。 :p
What i did was
Works just fine the
ls -A my_directory
expands to everything in the directory except.
and..
. No wierd globs, and on a single line.ps: Perhaps someone will tell me why this is not a good idea. :p
通常我只会使用
。 .[a-zA-Z0-9]*
因为我的文件名往往遵循某些规则,但这不会捕获所有可能的情况。您可以使用:
它将基本上列出所有文件和目录,删除父目录,然后处理其余部分。但要注意文件名中的空格,它会将它们视为单独的文件。
当然,如果您只想处理文件,您可以使用:
或者,另一种解决方案,它应该处理除
..
之外的所有文件和目录:但现在您正在进入可能需要脚本或别名的领域。
Usually I would just use
. .[a-zA-Z0-9]*
since my file names tend to follow certain rules, but that won't catch all possible cases.You can use:
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:
or, yet another solution, which should do all files and directories except the
..
one:but now you're getting into territory where scripts or aliases may be necessary.
怎么样:
How about:
由于您可能不想为 bash 会话的其余部分设置 dotglob,因此您可以通过在子进程中运行来为一组命令设置它,如下所示:
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:
如果您确定永远不会使用两个字符的隐藏文件名,那么最简单的选择就是:
If you are sure that two character hidden file names will never be used, then the simplest option is just be to do: