Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Linux中基于父文件夹移动和重命名文件?_Linux_Bash_File_Command Line_Directory - Fatal编程技术网

如何在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的规格…不过改名很好