kin*_*986 5 command-line directory mkdir
假设我有以下目录结构,其中目录的名称无关紧要:
currentDir/
Dir1
Dir1
Dir1 *
Dir2 *
Dir3 *
Dir2
Dir1 *
Dir2
Dir1*
Dir3*
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以只在树枝末端的目录中创建一个名为“Texture”的目录(在示例中它们用 标记*
)。我想让它只让那些目录得到一个Texture
目录,而不是任何其他目录。
所有目录可能有也可能没有文件,但最终目录中不会有任何其他目录。
首先开启递归通配
shopt -s globstar
Run Code Online (Sandbox Code Playgroud)
现在我们可以查看所有目录**
。要取消设置,您可以使用shopt -u globstar
(默认情况下它是关闭的,因此当您打开新外壳时它会关闭)。
在以下所有内容中,echo
在测试后删除以实际创建目录。
如果树尾目录为空,您可以测试是否为空,并仅在检测到目录时才创建该目录......类似
for d in **/; do [[ -z "$(ls -Aq "$d")" ]] && echo mkdir "$d"Texture; done
Run Code Online (Sandbox Code Playgroud)
即如果输出ls -A (hidden files except current and parent dir) -q (printing ? for non-printing characters)
为空,则创建一个目录。
但是由于目录包含文件,我们最好测试一下没有目录
for d in **/; do [[ -z "$(find "$d" -maxdepth 1 -mindepth 1 -type d)" ]] && echo mkdir "$d"Texture; done
Run Code Online (Sandbox Code Playgroud)
mindepth -1
是停止找到当前目录...find
看到隐藏文件,所以我们知道这些文件被包含在内。由于任何字符都应该通过测试(我们只想检查输出是否为空),这应该是相当安全的......
一种更简洁的方式(对不起 Greg)(但实际上所有这些方法都做了类似的事情 - 我们可以避免使用文件名作为文本,因为我们实际上并没有在这里尝试对这些文件本身做任何事情):
for d in **/; do (ls -Alq "$d" | grep -q '^d') || echo mkdir "$d"Textures; done
Run Code Online (Sandbox Code Playgroud)
在这里我们添加了-l
长输出的标志,它打印表单中的每个文件
drwxrwxr-x 5 zanna zanna 4096 Sep 27 22:00 Dir1
Run Code Online (Sandbox Code Playgroud)
然后我们将这些东西吞入管道grep
以查看是否有任何行开头d
(意味着有一个目录)。我们不想grep
打印任何无意义的不可靠文本,所以我们只是检查它的退出状态,-q
看看它是否找到了任何东西。如果没有,我们创建一个目录(使用||
or 操作符,意思是,如果上一个失败,则执行下一个命令)。实际上,即使您的文件名包含可怕的字符(例如换行符),这也应该有效,因为将ls
它们打印为?
- 每行都应以指示文件类型的字母开头,因此,可能没有小猫会死。
这是一个痛苦的find -exec
电话
前:
$ tree currentDir
currentDir
??? Dir1
? ??? Dir1
? ? ??? Dir1
? ??? Dir2
? ??? Dir3
??? Dir2
? ??? Dir1
? ??? Dir2
? ??? Dir1
??? Dir3
Run Code Online (Sandbox Code Playgroud)
创建纹理目录
$ find currentDir -depth -type d -exec bash -c 'cd "$1"; shopt -s globstar nullglob; texture=(**/Texture); [[ ${#texture[@]} -eq 0 ]] && mkdir Texture' _ '{}' \;
Run Code Online (Sandbox Code Playgroud)
这取决于:
-depth
启用深度优先导航的选项globstar
shell 选项来启用递归文件模式匹配_
参数:进入 bash var$0
以便 find 的当前路径名可以是 bash var$1
后
$ tree currentDir
currentDir
??? Dir1
? ??? Dir1
? ? ??? Dir1
? ? ??? Texture
? ??? Dir2
? ? ??? Texture
? ??? Dir3
? ??? Texture
??? Dir2
? ??? Dir1
? ? ??? Texture
? ??? Dir2
? ??? Dir1
? ??? Texture
??? Dir3
??? Texture
Run Code Online (Sandbox Code Playgroud)