使用路径名重命名文件

使用路径名重命名文件

我的子文件夹中有一个 .bdf 文件。所有 .bdf 都具有相同的名称:Loads.bdf

例子:

/home/user/folderxx/folderxxx/Load.bdf
/home/user/folderxx/folderxxx/Load.bdf

我需要找到(并复制到新文件夹)所有 Load.bdf 文件并用其路径名重命名它们。

示例:在预期的操作之后,它应该显示类似这样的内容。

folder001_folderAAA_Load.bdf
folder002_folderBBB_Load.bdf

答案1

我将使用(“多次移动”)包mcp中的工具:mmv

mcp '/home/user/*/*/Load.bdf' '#1_#2_Load.bdf'

#1第二个字符串中的等#2将替换为第一个字符串中相应的第一个、第二个等通配符的内容。请注意,路径用单引号括起来,以便通配符由 解释mcp,而不是由 shell 解释。

使用显示的命令,文件将被复制到当前目录。如果替换mcpmmv,文件将被移动。

答案2

使用prename(在许多系统上别名为rename)可以在不多次运行mvor的情况下完成此操作cp

cd /home/user
find . -type f -name 'Loads.bdf' -exec \
  prename -n 's:^./::; s:/:_:g; s:^:destination/:' {} +

-n当您确定这正在移动您想要的文件时,请删除。

更新

要复制文件而不是移动它们,最快的方法是先使用cpiopax进行复制,然后像以前一样重命名。例如(使用 GNU cpio):

cd /home/user
find . -type f -name 'Loads.bdf | cpio -p --make-directories destination

cd destination
find . -type f -name 'Loads.bdf' -exec  prename -n 's:^./::; s:/:_:g' {} +

请注意,虽然pax既是 POSIX 又是 LSB,并且cpio不再是 POSIX,但cpio仍然是许多系统中常见的程序。

find要使用 GNU /处理带有换行符的文件名,cpio可以添加-print0find-0cpio.

更新2

解决pax方案是一行(不包括cd):

cd /home/user
find . -name 'Loads.bdf' | cut -d/ -f 2- | pax -rws ':/:_:g' destination

或者对于任何文件名(和 GNU find):

find /home/user -name 'Loads.bdf' -printf '%P\0' | pax -0rws ':/:_:g' destination

答案3

如果您碰巧需要在没有其他一些答案中提到的工具(例如 mcp 和 mmv 或 prename)的系统上执行此操作,并且您想完全在 shell 中执行此操作,则可以执行某些操作喜欢:

#!/usr/bin/env bash

oldpath="/home/user"
newpath="/home/user/newfolder"

for file in $(find $oldpath -type f -name Load.bdf); do
        shortname=${file#$oldpath/}
        newname="$newpath/${shortname//\//_}"
        if [ -f $newname ]; then
                echo "$newname already exists."
        else
                echo "copy: $file"
                echo "  --> $newname"
                cp $file $newname
        fi
done

Load.bdf该脚本将查找目录中指定的所有文件oldpath,将目录名称合并为新文件名,然后将它们复制到目标目录。我们还可以检查已复制的文件是否存在,以防您需要多次运行它,并且我们不需要再次复制所有文件。

最终的目录结构将如下所示:

bash$ find . -type f
/home/user/folder001/folderAAA/Load.bdf
/home/user/folder002/folderBBB/Load.bdf
/home/user/folder003/folderCCC/Load.bdf
/home/user/newfolder/folder001_folderAAA_Load.bdf
/home/user/newfolder/folder002_folderBBB_Load.bdf
/home/user/newfolder/folder003_folderCCC_Load.bdf

答案4

env - sh <<\SCRIPT

    t=/home/user/target f=folder
    cd "${t%/*}" && mkdir -p "$t"
    set -- $f??/$f???/Load.BDF
    while [ -e "$1" ] ; do
        cp "$1" "$t/$(IFS=/
            printf '%s_%s_%s\n' $1)"
    shift ; done

SCRIPT

我认为这都是完全可移植的 shell 脚本 - 尽管我一开始对此表示怀疑,但完成起来非常简单。

相关内容