使用像我这样的 shell 模式,{abc,def}xyz
可以使用它来创建尚不存在的文件(或目录):
$ ls
$ touch {abc,def}xyz
$ mkdir 123{a,b,c}
$ ls
123a 123b 123c abcxyz defxyz
让我困惑的是如何在一组匹配模式的文件夹中的每一个中创建一个子目录。例如,现在我有了123a
、123b
、 ,123c
我可以在每个目录中创建一个子目录,而不必显式列出它们吗?
$ mkdir {12*}/rsnapshot # Fails because 12* isn't a list
$ mkdir 12*/rnapshot # Fails because 12*/rsnapshot doesn't exist
$ mkdir 123{a,b,c}/rsnapshot # Succeeds but more complex than I'd like
最后一个示例有效,但要求我在子条款中列出每个目录名称的某些部分{...}
。如果我有大量目录,这是不可能的。
我还让这一行适用于不包含空格的简单名称,但对于通用解决方案来说,它既不明显也不优雅:
echo -n 12* '' | xargs -r -d ' ' -I {} echo mkdir {}/rsnapshot
是否有一个模式模板bash
允许我在一大组类似命名的子目录中创建文件或子目录而无需循环?
答案1
只需重新调用以前的命令参数即可!$
mkdir 123{a,b,c}
mkdir !$/rsnapshot
如果您不打算使用 find 在模式指定的目录名称中创建子目录循环。
find . -maxdepth 1 -type d -name "123*" -exec mkdir '{}/rsnapshot' \;
答案2
dirs=( 123* )
set -- "${dirs[@]/%//deep/and deeper}"
mkdir -p "$@"
我想这不需要解释...
答案3
我认为没有机会获得“比 123{a,b,c}/rsnapshot 更简单”的解决方案。但也许我们对事情的复杂性的看法差异很大......
但我可以提供一些“类似贝壳”的东西。不幸的是,似乎不可能(使用bash
)配置分隔路径名扩展所产生的元素的字符,因此它变得更加复杂:
:> dirs=(12*/.) # the dot makes it match directories only
:> echo ${dirs[*]}
123a/. 123b/. 123c/.
:> IFS=,
:> eval echo mkdir -p "{${dirs[*]}}/rsnapshot"
mkdir -p 123a/./rsnapshot 123b/./rsnapshot 123c/./rsnapshot
当然,只有当路径名扩展匹配都不包含逗号时,这才有效。这可以通过 来防止$GLOBIGNORE
。
printf
和xargs
我纠正一下:
printf "%s/rsnapshot\0" 12*/. | xargs -0 echo mkdir -p
答案4
看来(从其他允许的答案来看)任何123
目录都是有效的:
dirs=(123*/)
mkdir "${dirs[@]/%/rsnapshot}"