将文件从子目录移动到单个目录并为原始目录名称添加前缀

Bra*_*yer 5 linux bash mv ubuntu

我有一个这样的目录结构:

./a/1.png
./a/2.png
./a/3.png
./b/1.png
./b/2.png
./b/3.png
./c/1.png
...
Run Code Online (Sandbox Code Playgroud)

我想获取子目录中的所有文件并将它们移动到一个新目录中,这样它们的名称就类似于

../dest/a_1.png
../dest/a_2.png
../dest/a_3.png
../dest/b_1.png
../dest/b_2.png
../dest/b_3.png
../dest/c_1.png
...
Run Code Online (Sandbox Code Playgroud)

我能够找到的最接近的方法是在不编写脚本来逐个文件地执行此操作的情况下使用find--backup=numbered选项,该选项会将我的文件压缩到单个目录,但最终会丢失文件名中的目录上下文。

有没有简洁的方法来实现这一目标?

Cyr*_*rus 11

使用 Perl 的独立rename命令:

rename -n 's|/|_|; s|^|dest/|' */*.png
Run Code Online (Sandbox Code Playgroud)

输出:

a/1.png 重命名为 dest/a_1.png
a/2.png 重命名为 dest/a_2.png
a/3.png 重命名为 dest/a_3.png
b/1.png 重命名为 dest/b_1.png
b/2.png 重命名为 dest/b_2.png
b/3.png 重命名为 dest/b_3.png
c/1.png 重命名为 dest/c_1.png

如果一切正常,请删除 option -n


slh*_*hck 6

使用 Bash 4 和递归通配符 ( shopt -s globstar):

for f in **/*.png; do
  dn=$(basename "$(dirname "$f")")
  bn=$(basename "$f")
  mv -- "$f" "../dest/${dn}_${bn}"
done
Run Code Online (Sandbox Code Playgroud)

请注意,dirname /foo/bar/baz返回/foo/bar而不仅仅是bar,这就是为什么您必须调用basename结果才能获取bar,以防万一您正在从另一个父文件夹工作。