带有通配符和隐藏文件的 Bash for 循环

发布于 2024-08-18 18:13:32 字数 625 浏览 2 评论 0原文

只是知道一个简单的 shell 脚本,有点困惑:

这是我的脚本:

% for f in $FILES; do echo "Processing $f file.."; done

命令:

ls -la | grep bash 

产生:

% ls -a | grep bash
.bash_from_cshrc
.bash_history
.bash_profile
.bashrc

FILES=".bash*"

我得到与 ls -a 相同的结果(不同的格式)时。然而,当

FILES="*bash*"

我得到这个输出时:

Processing *bash* file..

这不是预期的输出,也不是我所期望的。文件名开头是否不允许有通配符?是 .以某种方式在文件名“特殊”的开头?

设置

FILES="bash*"

也不起作用。

Just witting a simple shell script and little confused:

Here is my script:

% for f in $FILES; do echo "Processing $f file.."; done

The Command:

ls -la | grep bash 

produces:

% ls -a | grep bash
.bash_from_cshrc
.bash_history
.bash_profile
.bashrc

When

FILES=".bash*"

I get the same results (different formatting) as ls -a. However when

FILES="*bash*"

I get this output:

Processing *bash* file..

This is not the expected output and not what I expect. Am I not allowed to have a wild card at the beginning of the file name? Is the . at the beginning of the file name "special" somehow?

Setting

FILES="bash*"

Also does not work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(6

忘羡 2024-08-25 18:13:32

bash 中的默认通配符不包括以 . (又名隐藏文件)。

你可以改变它

shopt -s dotglob

$ ls -a
.  ..  .a  .b  .c  d  e  f
$ ls *
d  e  f
$ shopt -s dotglob
$ ls *
.a  .b  .c  d  e  f
$ 

要再次禁用它,请运行 shopt -u dotglob

The default globbing in bash does not include filenames starting with a . (aka hidden files).

You can change that with

shopt -s dotglob

$ ls -a
.  ..  .a  .b  .c  d  e  f
$ ls *
d  e  f
$ shopt -s dotglob
$ ls *
.a  .b  .c  d  e  f
$ 

To disable it again, run shopt -u dotglob.

澜川若宁 2024-08-25 18:13:32

如果你想要隐藏和非隐藏,设置dotglob(bash)

#!/bin/bash
shopt -s dotglob
for file in *
do
 echo "$file"
done

If you want hidden and non hidden, set dotglob (bash)

#!/bin/bash
shopt -s dotglob
for file in *
do
 echo "$file"
done
临风闻羌笛 2024-08-25 18:13:32

FILES=".bash*" 有效,因为隐藏文件名以 . 开头

FILES="bash*" 不起作用,因为隐藏文件名以 . 开头,而不是 b

FILES="*bash*" 不起作用,因为 * 字符串开头的通配符会省略隐藏文件。

FILES=".bash*" works because the hidden files name begin with a .

FILES="bash*" doesn't work because the hidden files name begin with a . not a b

FILES="*bash*" doesn't work because the * wildcard at the beginning of a string omits hidden files.

失与倦" 2024-08-25 18:13:32

是的,前面的 . 很特殊,通常不会与 * 通配符匹配,如 bash 手册页中所述(对于大多数 Unix shell 来说很常见) ):

当模式用于路径名扩展时,字符“.”
必须位于名称开头或紧跟在斜杠之后
显式匹配,除非 shell 选项 dotglob
放。匹配路径名时,斜杠字符必须
始终明确匹配。在其他情况下,“.”
角色没有受到特殊对待。

Yes, the . at the front is special, and normally won't be matched by a * wildcard, as documented in the bash man page (and common to most Unix shells):

When a pattern is used for pathname expansion, the character “.”
at the start of a name or immediately following a slash must
be matched explicitly, unless the shell option dotglob is
set. When matching a pathname, the slash character must
always be matched explicitly. In other cases, the “.”
character is not treated specially.

时光倒影 2024-08-25 18:13:32

如果要包含隐藏文件,可以指定两个通配符;一个用于隐藏文件,另一个用于其他文件。

for f in .[!.]* *; do
    echo "Processing $f file.."
done

通配符 .* 将扩展到所有点文件,但包括您通常希望排除的父目录;因此 .[!.]* 匹配第一个字符是点但第二个字符不是点的所有文件。

如果您还有其他带有两个前导点的文件,则需要指定第三个通配符来覆盖这些文件,但排除父目录!尝试 ..?* ,它要求第二个点之后至少有一个字符。

If you want to include hidden files, you can specify two wildcards; one for the hidden files, and another for the others.

for f in .[!.]* *; do
    echo "Processing $f file.."
done

The wildcard .* would expand to all the dot files, but that includes the parent directory, which you normally would want to exclude; so .[!.]* matches all files whose first character is a dot, but the second one isn't.

If you have other files with two leading dots, you need to specify a third wildcard to cover those but exclude the parent directory! Try ..?* which requires there to be at least one character after the second dot.

与之呼应 2024-08-25 18:13:32
for file in directory/{.[!.]*,*};do echo $file;done

应回显隐藏文件和普通文件。感谢 Tripleee 提供的 .[!.]* 提示。
大括号允许在模式匹配中使用“或”。 {模式1,模式2}

for file in directory/{.[!.]*,*};do echo $file;done

Should echo either hidden files and normal file. Thanks to tripleee for the .[!.]* tip.
The curly brackets permits a 'or' in the pattern matching. {pattern1,pattern2}

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