如何将分散在文件系统中的所有同名文件移动到一个文件夹中?

如何将分散在文件系统中的所有同名文件移动到一个文件夹中?

我有一个文件系统树,其中的不同位置都有同名的文件。我在命令行尝试了以下命令:

find / -name "HAHA" -exec mv {} /home \;

它仅适用于一个文件,对于其他文件,我收到一条具有相同名称的错误消息。

我可以更改命令,为每个文件名附加一个数字来区分它们吗?

在此输入图像描述

答案1

我可以想到两种可能的解决方案:

  1. 如果您是mvGNU 核心工具(可能是这种情况),然后执行以下命令...

    find / -name "HAHA" -type f -exec mv --backup=numbered "{}" /home \;
    

    ...将把所有调用的文件移动HAHA/home.这--backup=numbered 选项ofmv确保每次mv执行该命令时,它都会检查目标目录中是否已存在指定的文件HAHA- 如果存在,则首先将其重命名为HAHA.~n~(其中n是递增的数字),然后再将新文件移动到/home。最后,您将得到名为HAHAHAHA.~1~HAHA.~2~的文件/home

  2. 这个 shell 脚本应该可以解决问题,但它不能抵抗包含换行符的路径:

    IFS="
    "      # if you are using bash, you can just use IFS=$'\n' here
    i=1
    for file in $(find / -name "HAHA" -type f); do
      mv "${file}" "/home/HAHA${i}"
      i=$((${i} + 1))
    done
    

    这会迭代所有HAHA文件并将每个文件移动到/home/HAHAn,其中的n数字又从 1 开始递增。

答案2

我找到了一个带有小脚本的简单解决方案。该脚本被称为cpf(或您给它起的任何名称),如下所示:

#!/bin/bash

dir=xyz       # Directory where you want the files
num=1

for file in "$@"
do
    base=`basename -- "$file"`
    mv -- "$file" "$dir/$base.$num"
    num=$(($num+1))
done

您执行命令如下:

find . -name HAHA -print0 | xargs -0x cpf

答案3

我会使用while循环:

i=1
find / -name 'HAHA' -print0 | while read -d '' -r file; do mv "$file" "/home/${file##.*/}$((i++))"; done

这里重要的是其中print0的选项find(与-d ''选项一起read)正确处理名称中带有空格的文件。如果您只需要执行一次此类操作,则i=1不需要设置第一行,因为bash(以及大多数其他 shell)将简单地自动创建此变量。

答案4

可以使用 GNU 并行

find / -name "HAHA" -type f | parallel 'echo mv {}
 ./dest-dir/{/}_`stat -c%i {}`

{/}  ............. returns dirname
{/.} ............. dirname with no extension
stat -c%i {} ..... gets the inode for each file "whic is unique"

OBS:我是echo为了测试而使用的,如果满足你的需求就删除它

相关内容