通配符扩展

通配符扩展

我不太清楚如何表述这一点,也许这就是我找不到任何东西的原因,但我想在命令中重用通配符枚举的值。这可能吗?

设想:

$ 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

相关内容