【问题标题】:How to use the .* wildcard in bash but exclude the parent directory (..)?如何在bash中使用.*通配符但排除父目录(..)?
【发布时间】:2011-02-24 00:00:58
【问题描述】:

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

chmod g+w * .*

它更改了我想要的所有文件(在目录中)和父目录中的所有文件(我想单独留下)的权限。

是否有通配符可以做正确的事情,还是我需要开始使用 find?

【问题讨论】:

    标签: bash wildcard


    【解决方案1】:

    通常我只会使用. .[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
    

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

    【讨论】:

    • 只需删除 grep -v '^.$' 因为 Allan 想要隐藏文件而不是父文件夹
    【解决方案2】:

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

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

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

    这应该适用于大多数 shell,并且适用于脚本。


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

    # bash
    GLOBIGNORE=.:..
    echo .*
    

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

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

    # zsh
    setopt glob_dots
    
    # bash
    shopt -s dotglob
    
    
    # show all files, even “dot files”
    echo *
    

    【讨论】:

    • 实际上,GLOBIGNORE 是一个不错的选择。如果您不想使其永久化,您可以使用( GLOBIGNORE=.. ; echo .* ) 暂时进行此操作。 +1 仅针对那一点信息。
    • '.[^.]* ..?*' glob 有一个警告,它通常会抱怨 ..?* 部分不匹配,除非您购买 nullglob。跨度>
    【解决方案3】:

    怎么样:

    shopt -s dotglob
    chmod g+w ./* 
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        我做的是

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

        工作得很好ls -A my_directory 扩展到目录中除... 之外的所有内容。没有奇怪的球体,而且在一条线上。

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

        【讨论】:

        • 是的,它工作正常(ls 中的“几乎全部”选项,但是,要这样做,您现在正在启动另一个进程,在这种情况下 /bin/ls.. 通常不是一个坏主意,但是如果您正在处理 10,000 多个目录,它可能会开始占用一点资源——通配是由 shell 完成的,不会启动任何进程来生成列表,实际上大多数人都可以侥幸逃脱只是使用 .[^.] 基本上看起来像一个戴着单片眼镜的光头男人,所以很容易记住(加上它与正则表达式非常相似,现在不是每个人都知道正则表达式吗?或者我在这里不正常吗>:)
        • 如果文件名包含空格,则会失败。
        【解决方案6】:

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

        chmod g+w * ...*
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-11-07
          • 1970-01-01
          • 2012-02-27
          • 2011-12-29
          • 2020-10-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多