将子目录中的所有文件移动到当前目录,同时重命名重复文件

将子目录中的所有文件移动到当前目录,同时重命名重复文件

我有多个子目录,我想使用 Mac 上的一行终端命令将其中包含的所有文件移动到当前目录。我知道我的文件名并不都是唯一的,我想在文件扩展名前添加后缀。

我发现了类似的问题问:将子目录中的所有文件移动到当前目录?建议使用:

find ./*/* -type f -print0 | xargs -0 -J % mv % . 

但这只对唯一的文件名有用。例如,给定以下树:

.
├── bar
│   ├── test1.jpg
│   ├── test2.jpg
│   └── test3.jpg
├── foo
│   ├── test1.jpg
│   ├── test2.jpg
│   └── test3.jpg
├── qux
│   └── test3.jpg
└── corge
    └── test3.jpg

我希望看到类似的结果:

.
├── bar
├── foo
├── qux
├── corge
├── test1.jpg
├── test1a.jpg
├── test2.jpg
├── test2a.jpg
├── test3.jpg
├── test3a.jpg
├── test3b.jpg
└── test3c.jpg

有人可以帮忙吗?

答案1

获取当前目录中每个文件的所有常规文件的递归列表,剪切其中的前导“。”和斜线,将目录和文件名连接成一个唯一的字符串,然后将其移动到当前目录

list=$(find . -type f)
for file in $list; do
   echo -n "$file to "
   echo $file|cut -d '.' -f2-99| tr -d '/'
   mv "$file" ./"$(echo $file|cut -d '.' -f2| tr -d '/')"
done

答案2

将此脚本复制到您的顶级目录,使其可执行并运行它:

#!/bin/bash

## Get a list of all files
list=$(find . -mindepth 2 -type f -print)
nr=1

## Move all files that are unique
find . -mindepth 2 -type f -print0 | while IFS= read -r -d '' file; do
    mv -n "$file" ./
done
list=$(find . -mindepth 2 -type f -print)

## Checking which files need to be renamed
while [[ $list != '' ]] ; do
   ##Remaming the un-moved files to unique names and move the renamed files
   find . -mindepth 2 -type f -print0 | while IFS= read -r -d '' file; do
       current_file=$(basename "$file")
       mv -n "$file" "./${nr}${current_file}"
   done
   ## Incrementing counter to prefix to file name
   nr=$((nr+1))
   list=$(find . -mindepth 2 -type f -print)
done

答案3

除非您的示例中的严格顺序命名对您来说非常重要,否则我建议采用以下“保持简单”/“快速而肮脏”的解决方案:

find . -type f |
while read filename; do
    basename=$(basename "$filename");
    newname=$(echo "$basename" | sed "s/^\(.*\)\(\.[^\.]\+\)$/\1(XXXX)\2/");
    printf "mv \"%s\" \"%s\";\n" "$filename" "$(mktemp -u "$newname")";
done

这只会打印将要执行的命令,因此请通过检查输出来检查其合理性,然后复制并粘贴到命令行中,如果一切都令您满意。

用英文来说:找到所有常规文件,将它们的文件名从“test1.jpg”转换为“test1(XXXX).jpg”形式,其中“XXXX”将被挑选出来并由 mktemp 用随机字符替换,然后为此操作创建“mv”命令行。

为了进一步降低文件名冲突风险,只需添加更多“X”即可。

玩得开心。

相关内容