如何在Linux中基于父文件夹移动和重命名文件?

时间:2013-06-30 06:15:28

标签: linux bash file command-line directory

我有一个名为photos的文件夹,其结构如下:

00001/photo.jpg
00002/photo.jpg
00003/photo.jpg

我想:

  1. 将文件夹(名为photo.jpg)中的文件重命名为父文件夹。
  2. 将其移动到文件夹中。
  3. 删除父文件夹。
  4. 所以photos文件夹就是这样的:

    00001.jpg
    00002.jpg
    00003.jpg
    

    如何在Linux的终端中执行此操作?

    注意。 photos中有100000多个此类文件夹。

6 个答案:

答案 0 :(得分:5)

自从我在评论中读到你有100000多个这样的目录后发布了帖子。

使用任何涉及bash globbing的方法,它会非常慢且效率低下。而是在find目录中使用此photos命令:

find -regex '\./[0-9]+' -type d -exec mv -n -- {}/photo.jpg {}.jpg \; -empty -delete

我已使用-n选项mv,因此我们不会覆盖现有文件。如果您的mv版本支持,请使用它。您还可以使用-v选项,以便mv详细,您可以看到发生了什么:

find -regex '\./[0-9]+' -type d -exec mv -nv -- {}/photo.jpg {}.jpg \; -empty -delete

将上一个命令读作:

  • -regex '\./[0-9]+':查找当前目录中名称中只有数字的所有内容
  • -type d:它必须是目录
  • -exec mv -n -- {}/photo.jpg {}.jpg \;:将此目录中的photo.jpg文件移至父目录,名称为:dirname.jpg
  • -empty:如果目录现在为空......
  • -delete:...删除它。

之后,您可能希望查看哪些目录尚未删除(例如,它包含的文件多于photo.jpg文件):

find -regex '\./[0-9]+' -type d

享受!

答案 1 :(得分:2)

cd $toTheRootFolderWhichYouHaveALLtheFolders #00001, 00002
mv 00001/photo.jpg 00001.jpg

或者您可以在“照片”目录中使用此bash脚本:

for entry in ./*; 
 do  
    mv "$entry"/photo.jpg "$entry".jpg ;
    rm -rf "$entry";
 done

答案 2 :(得分:0)

使用for循环,printf -v将计数器填零。例如:

for ((i=1;i<4;i++))
do 
    printf -v num "%05d" "$i"; 
    mv "$num"/photo.jpg "$num".jpg
done

答案 3 :(得分:0)

您可以执行以下操作:

find . -type f | while read -r file; do mv "$file" "${file%/*}"".jpg" ; done

将所有文件重命名并移至父文件夹后,可以运行以下命令删除所有空文件夹。

find . -type d -empty -exec rm -rf {} +

请记住,上述解决方案仅适用于您提供的结构。如果任何子文件夹中有多个文件,并且您希望将其重命名为父目录名,则它将被覆盖。

答案 4 :(得分:0)

据我了解,这应该做你想要的。

# Setup test data according to your structure
$ mkdir 00001 00002 00003 
$ touch 00001/photo.jpg 00002/photo.jpg 00003/photo.jpg

# Rename, these are the commands you'll want to run to rename
$ ls ?????/photo.jpg | xargs -I {} sh -c 'mv {} $(echo {} | sed "s,/photo,,")'
$ rmdir  ?????

# Verify that the renames went ok
$ ls
00001.jpg   00002.jpg   00003.jpg

答案 5 :(得分:0)

我使用的一种简单方法是从ls */*.jpg(或只是ls */*)获取输出并处理输出以形成像mv 00001/photo.jpg ./00001.jpg这样的移动命令,你可以然后使用rmdir 00001以类似的方法轻松清理空文件夹。

要在bash终端类型使用awk执行此操作:

ls */* | awk -F'/' '{print "mv " $0 " ./" $1 "_" $2 }' | bash
ls */ | awk -F'/' '{print "rmdir " $1 }' | bash

您可以在运行命令之前轻松预览命令,方法是在行尾不用| bash(查看生成的命令是什么,并在将它们传输到bash之前修复语法错误以执行它们)

不幸的是,ls */的输出包含空行,这些空行会弄乱你的rmdir,但不会阻止它产生所需效果。

我发现这种方法非常强大/灵活,比编写循环更容易。使用对您有意义的方法。