我正在尝试为目录中的每个文件创建一个目录。
mkdir *
返回文件存在。所以我尝试
mkdir *.d
它创建一个名为“*.d”的目录。如何强制扩展通配符?
答案1
通配符总是扩展为现存的名称。
您的命令mkdir *
失败,因为扩展的名称*
已存在。
您的命令mkdir *.d
“失败”,因为它*.d
与任何现有名称都不匹配。因此,默认情况下该模式不会展开1*.d
并创建一个名为 的目录。您可以使用 删除它rmdir '*.d'
。
为每个目录创建一个目录常规文件在当前目录中,以便新目录与文件具有相同的名称,但带有后缀.d
:
for name in ./*; do
if [ -f "$name" ]; then
# this is a regular file (or a symlink to one), create directory
mkdir "$name.d"
fi
done
或者,对于喜欢“俏皮话”的人来说,
for n in ./*; do [ -f "$n" ] && mkdir "$n.d"; done
在 中bash
,你也可以这样做
names=( ./* )
mkdir "${names[@]/%/.d}"
但这不会检查 glob 扩展为的内容是常规文件还是其他文件。
上述命令中的首字母./
是为了防止文件名-
中包含首字母破折号 ( ) 的文件名。否则,破折号及其后面的字符将被解释为 的选项mkdir
。
1 某些 shell 具有一个nullglob
shell 选项,该选项会导致不匹配的 shell 通配符扩展为空字符串。在bash
此启用使用shopt -s nullglob
。
答案2
for foo in bar; do baz; done
我建议的不是解决方案:
find . -maxdepth 1 -type f -print0|xargs -0 -I file mkdir file.d
答案3
*.d
扩展到名称以.d
.
有了zsh
,你可以这样做:
files=(*)
mkdir -- $^files.d
或者使用匿名函数:
() { mkdir -- $^argv.d; } *
或者通过 glob 限定符添加后缀e
:
mkdir -- *(e{REPLY+=.d})
或者:s
应用于 glob 的历史修饰符(使用histsubstpattern
for%
表示结尾):
set -o histsubstpattern
mkdir -- *(:s/%/.d)
您可能还不想通过添加^-/
glob 限定符来对已经是目录或目录符号链接的文件执行此操作:
files=(*(^-/))
mkdir -- $^files.d
(请注意,它zsh
没有其他类似 Bourne 的 shell 的缺陷,其中不匹配的模式会按原样传递,因此如果当前目录中没有匹配的文件,mkdir *.d
则不会创建目录,它将中止命令而是出现错误)*.d
*.d