如何在删除部分路径的同时递归复制文件

时间:2018-12-18 16:25:52

标签: bash

我在这样的结构中有数百个图像文件:

path / to / file / 100 / image1.jpg

path / to / file / 9999 / image765.jpg

path / to / file / 333 / picture2.jpg

我想删除路径的第四部分(100,9999,333,...),以便得到此信息:

path / to / file / image1.jpg

path / to / file / image765.jpg

path / to / file / picture2.jpg

在这种情况下,图像文件名没有重复,如果可以简化操作,则可以将目标目录命名为完全不同的名称(例如,目标可以是“ another / path / to / the / images / image1.jpg”

解决方案可能是find / cut / rename命令的某种组合。

如何在bash中执行此操作?

2 个答案:

答案 0 :(得分:1)

由于您只有“数百”个文件,因此很有可能不需要执行任何特殊操作,而只需编写:

mv path/to/file/*/*.jpg path/to/file/

但是取决于文件的数量和文件名的长度,这可能超出内核允许您传递给单个命令的范围,在这种情况下,您可能需要编写for-改为循环:

for file in path/to/file/*/*.jpg ; do
    mv "$file" path/to/file/
done

(当然,这假设您在路径上有mv。没有内置Bash来重命名文件,因此任何方法都将取决于系统上的其他可用方式。如果您没有{ {1}},您需要相应地进行调整。)

答案 1 :(得分:0)

如果可以使用ruakh解决方案,我建议使用ruakh的解决方案,但是如果您需要显式测试这些数字目录,则可以选择这种方法。

我只是使用echo来输入名称列表,并在末尾显示mv,但是您可以使用find(注释示例)和移除echo上的mv使其生效。

IFS=/ 
echo "path/to/file/100/image1.jpg
path/to/file/9999/image765.jpg
path/to/file/333/picture2.jpg" |
#   find path/to/file -name "*.jpg" |
while read -r orig
do this=""
   read -a line <<< "$orig" 
   for sub in "${line[@]}"
   do  if [[ "$sub" =~ ^[0-9]+$ ]]
       then continue
       else this="$this$sub/"
       fi
   done
   old="${line[*]}"
   echo mv "$old" "${this%/}" 
done
mv path/to/file/100/image1.jpg  path/to/file/image1.jpg
mv path/to/file/9999/image765.jpg  path/to/file/image765.jpg
mv path/to/file/333/picture2.jpg path/to/file/picture2.jpg