如何在Linux中基于父文件夹移动和重命名文件?
我有一个名为如何在Linux中基于父文件夹移动和重命名文件?,linux,bash,file,command-line,directory,Linux,Bash,File,Command Line,Directory,我有一个名为photos的文件夹,其结构如下: 00001/photo.jpg 00002/photo.jpg 00003/photo.jpg 我想: 将文件夹(名为photo.jpg)中的文件重命名为父文件夹 将其向上移动一个文件夹 删除父文件夹 因此,photos文件夹应该是这样的: 00001.jpg 00002.jpg 00003.jpg 如何在Linux终端中执行此操作? 注意。照片中有100000多个这样的文件夹 cd $toTheRootFolderWhichYouHaveAL
photos
的文件夹,其结构如下:
00001/photo.jpg
00002/photo.jpg
00003/photo.jpg
我想:
photo.jpg
)中的文件重命名为父文件夹photos
文件夹应该是这样的:
00001.jpg
00002.jpg
00003.jpg
如何在Linux终端中执行此操作?
注意。照片中有100000多个这样的文件夹
cd $toTheRootFolderWhichYouHaveALLtheFolders #00001, 00002
mv 00001/photo.jpg 00001.jpg
或者您可以在“photos”目录中使用此bash脚本:
for entry in ./*;
do
mv "$entry"/photo.jpg "$entry".jpg ;
rm -rf "$entry";
done
find -regex '\./[0-9]+' -type d -exec mv -n -- {}/photo.jpg {}.jpg \; -empty -delete
使用for循环,并printf-v
将计数器归零。例如:
for ((i=1;i<4;i++))
do
printf -v num "%05d" "$i";
mv "$num"/photo.jpg "$num".jpg
done
对于((i=1;i您可以执行以下操作:
find . -type f | while read -r file; do mv "$file" "${file%/*}"".jpg" ; done
重命名所有文件并向上移动到父文件夹后,可以运行以下命令删除所有空文件夹
find . -type d -empty -exec rm -rf {} +
请记住,上述解决方案仅适用于您提供的结构。如果您在任何子文件夹中有多个文件,并且希望将其重命名为父目录名,则会被覆盖。据我所知,这应该可以满足您的要求
# 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
因为我在评论中读到你有100000多个这样的目录,所以进行了后期编辑。
不要使用任何涉及bash globbing的方法,这将非常缓慢且效率低下。相反,请在photos
目录中使用此find
命令:
for entry in ./*;
do
mv "$entry"/photo.jpg "$entry".jpg ;
rm -rf "$entry";
done
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]+'
:查找当前目录中名称中只有数字的所有内容
-键入d
:它必须是一个目录
-exec mv-n--{}/photo.jpg{}.jpg\
:将此目录中的photo.jpg
文件移到父目录中,文件名为:dirname.jpg
-empty
:如果目录现在为空
-删除
:…删除它
之后,您可能希望查看哪些目录未被删除(例如,它包含的文件多于photo.jpg
文件):
享受!我使用的一种简单方法是从类似于ls*/*.jpg
(或只是ls*/*
)的东西中获取输出,然后处理输出以形成移动命令,如mv00001/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
,但不会阻止它产生所需的效果
我发现这种方法非常强大/灵活,比编写循环脚本更简单。使用对您有意义的方法。谢谢,但我有100000多个这样的文件夹。逐个执行?创建一个wtv.sh
文件,用您最喜欢的文本编辑器编辑,并将代码粘贴到#!/bin/bash
作为标题。然后设置上一个推断执行脚本chmod+xwtv.sh
,您就可以开始了。或者在“根文件夹”中你有另一个文件夹类型sh
并粘贴代码。@mrz mkdir/touch的任务是根据他的问题设置文件,以演示#rename
部分中的重命名。编辑以使其更清晰。我只是发现,如果没有可以首先使用的测试用例,重命名100k文件有点可怕。他不需要设置他的“规格”既然他已经有了他的规格,答案应该一直是针对OP的规格…不过改名很好