我不太清楚如何表述这一点,也许这就是我找不到任何东西的原因,但我想在命令中重用通配符枚举的值。这可能吗?
设想:
$ ls /dir 1 2 3
/dir 的内容是目录 1、2 和 3。
$ cp /dir/*/file .
导致文件从 /dir/1 /dir/2 和 /dir/3 复制到这里。
我想要做的是根据通配符扩展将文件复制到新的目标名称。
$ cp /dir/*/file ???-file
会导致 /dir/*/file 被复制到 1-file、2-file 和 3-file。我无法弄清楚的是???
告诉 Bash 我想要使用通配符扩展值的部分。
在目标中使用通配符会导致cp
错误:
cp: target `*-file' is not a directory.
Bash 中还有其他东西可以在这里使用吗?
该find
命令必须与我上面寻找的类似{}
使用。-exec
答案1
ls /dir |while read dirname; do cp -v /dir/"$dirname"/file "$dirname"-file ; done
答案2
我的第一个想法是你可能把这个问题搞得太复杂了。然而,这是可以解决的。
你可以用疯狂的 bash 循环做这样的事情:
for i in /dir/*/file
do
j=${i%/file}
k=${j#/dir/}
cp $i %k-file
done
使用几个 bash字符串运算符提取源目录的号码。
我保证有更好的方法可以做到这一点,这只是我想到的。
答案3
zsh% autoload zmv # should be done for you, noting it just in case
zsh% zmv -C '(*)/file' '$1-file'
zmv 是一个 shell 函数,通常通过alias mmv='noglob zmv -W'
更简单的调用来使用,但在这种情况下您需要常规用法,加上 -C 来复制而不是移动。
答案4
在大多数发行版中(使用 util-linux 的改名):
rename /file -file /dir/*/file
关于 Debian 和 Ubuntu(归咎于 Debian):
rename.ul /file -file /dir/*/file
或者使用 Perl 的重命名(在 Debian 和 Ubuntu 上,我不知道在其他发行版中在哪里可以找到它):
rename 's,(\d+)/file,$1-file,' */file