我有一个名为photos
的文件夹,其结构如下:
00001/photo.jpg
00002/photo.jpg
00003/photo.jpg
我想:
photo.jpg
)中的文件重命名为父文件夹。所以photos
文件夹就是这样的:
00001.jpg
00002.jpg
00003.jpg
如何在Linux的终端中执行此操作?
注意。 photos
中有100000多个此类文件夹。
答案 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
,但不会阻止它产生所需效果。
我发现这种方法非常强大/灵活,比编写循环更容易。使用对您有意义的方法。