如何在 bash 中使用 .* 通配符但排除父目录 (..)?

发布于 2024-09-03 03:53:38 字数 177 浏览 1 评论 0原文

很多时候我想对目录中的所有文件(包括隐藏文件)执行命令。当我尝试使用

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

花想c 2024-09-10 03:53:38

您将需要两个 glob 模式来覆盖所有潜在的“点文件”:.[^.]*..?*

第一个匹配具有两个或多个字符的所有目录条目,其中第一个字符是点,第二个字符不是点。第二个选取包含三个或更多字符且以 .. 开头的条目(这不包括 ..,因为它只有两个字符并以 . 开头。 code>,但包括(不太可能)像 ..foo 这样的条目)。

chmod g+w .[^.]* ..?*

这应该在大多数 shell 中都能很好地工作,并且适合脚本。


对于常规的交互使用,这些模式可能太难记住。对于这些情况,您的 shell 可能有更方便的方法来跳过 ...
zsh 始终从 .* 等模式中排除 ...
对于 bash,您必须使用 GLOBIGNORE shell 变量。

# bash
GLOBIGNORE=.:..
echo .*

您可以考虑在您的 bash 自定义文件之一中设置 GLOBIGNORE(例如 .bash_profile/.bash_login.bashrc )。
但是,如果您经常使用其他环境,请注意,要习惯这种自定义。
如果您在缺少自定义的环境中运行像 chmod g+w .* 这样的命令,那么您将意外地最终包含 ...< /code> 在你的命令中。

此外,您可以将 shell 配置为在不以显式点开头的模式中包含“点文件”(例如 *)。

# zsh
setopt glob_dots

# bash
shopt -s dotglob


# show all files, even “dot files”
echo *

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).

chmod g+w .[^.]* ..?*

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.

# bash
GLOBIGNORE=.:..
echo .*

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. *).

# zsh
setopt glob_dots

# bash
shopt -s dotglob


# show all files, even “dot files”
echo *
淡淡離愁欲言轉身 2024-09-10 03:53:38

我所做的

tar --directory my_directory --file my_directory.tar --create `ls -A mydirectory/`

很好,ls -A my_directory 扩展到目录中除 ... 之外的所有内容。没有奇怪的球,并且在一行上。

ps:也许有人会告诉我为什么这不是一个好主意。 :p

What i did was

tar --directory my_directory --file my_directory.tar --create `ls -A mydirectory/`

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

浊酒尽余欢 2024-09-10 03:53:38

通常我只会使用。 .[a-zA-Z0-9]* 因为我的文件名往往遵循某些规则,但这不会捕获所有可能的情况。

可以使用:

chmod g+w $(ls -1a | grep -v '^..

它将基本上列出所有文件和目录,删除父目录,然后处理其余部分。但要注意文件名中的空格,它会将它们视为单独的文件。

当然,如果您只想处理文件,您可以使用:

find . -maxdepth 0 -type f -exec chmod g+w {} ';'

或者,另一种解决方案,它应该处理除..之外的所有文件和目录:

for i in * .* ; do if [[ ${i} != ".." ]] ; then chmod g+w "$i"; fi done

但现在您正在进入可能需要脚本或别名的领域。

)

它将基本上列出所有文件和目录,删除父目录,然后处理其余部分。但要注意文件名中的空格,它会将它们视为单独的文件。

当然,如果您只想处理文件,您可以使用:

或者,另一种解决方案,它应该处理除..之外的所有文件和目录:

但现在您正在进入可能需要脚本或别名的领域。

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:

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.

)

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.

月光色 2024-09-10 03:53:38

怎么样:

shopt -s dotglob
chmod g+w ./* 

How about:

shopt -s dotglob
chmod g+w ./* 
ゞ记忆︶ㄣ 2024-09-10 03:53:38

由于您可能不想为 bash 会话的其余部分设置 dotglob,因此您可以通过在子进程中运行来为一组命令设置它,如下所示:

$ (shopt -s dotglob; chmod g+w ./*)

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:

$ (shopt -s dotglob; chmod g+w ./*)
超可爱的懒熊 2024-09-10 03:53:38

如果您确定永远不会使用两个字符的隐藏文件名,那么最简单的选择就是:

chmod g+w * ...*

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 * ...*
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文