Home > Blockchain >  A bash script to rename files from different directories at once
A bash script to rename files from different directories at once

Time:02-22

If I have a directory named /all_images, and inside this directory there's a ton of directories, all the directories named dish_num as shown below. and inside each dish directory, there's one image named rgb.png. How can i rename all the image files to be the name of its directory.

Before

|
├── dish_1
│   └── rgb.png
├── dish_2
│   └── rgb.png
├── dish_3
│   └── rgb.png
├── dish_4
│   └── rgb.png
└── dish_5
    └── rgb.png

After

|
├── dish_1
│   └── dish_1.png
├── dish_2
│   └── dish_2.png
├── dish_3
│   └── dish_3.png
├── dish_4
│   └── dish_4.png
└── dish_5
    └── dish_5.png

CodePudding user response:

WARNING: Make sure you have backups before running code you got someplace on the Internet!

find /all_images -name rgb.png -execdir sh -c 'mv rgb.png $(basename $PWD).png' \;

where

  • find /all_images will start looking from the directory "/all_images"
  • -name rbg.png will look anywhere for anything named "rbg.png"
  • optionally use -type f to restrict results to only files
  • -exedir in every directory where you got a hit, execute the following:
  • sh -c shell script
  • mv move, or "rename" in this case
  • rgb.png file named "rgb.png"
  • $(basename $PWD).png output of "basename $PWD", which is the last section of the $PWD - the current directory - and append ".png" to it
  • \; terminating string for the find loop

CodePudding user response:

If you want to benefited from your multi-core processors, consider using xargs instead of find -execdir to process files concurrently.

Here is a solution composed of find, xargs, mv, basename and dirname.

find all_images -type f -name rgb.png |
  xargs -P0 -I@ sh -c 'mv @ $(dirname @)/$(basename $(dirname @)).png'
  1. find all_images -type f -name rgb.png prints a list of file paths whose filename is exactly rgb.png.

  2. xargs -P0 -I@ CMD... executes CMD in a parallel mode with @ replaced by path names from find command. Please refer to man xargs for more information.

    -P maxprocs Parallel mode: run at most maxprocs invocations of utility at once. If maxprocs is set to 0, xargs will run as many processes as possible.

  3. dirname all_images/dash_4/rgb.png becomes all_images/dash_4

  4. basename all_images/dash_4 becomes dash_4

Demo

mkdir all_images && seq 5 |
  xargs -I@ sh -c 'mkdir all_images/dash_@ && touch all_images/dash_@/rgb.png'
tree
find all_images -type f -name rgb.png |
  xargs -P0 -I@ sh -c 'mv @ $(dirname @)/$(basename $(dirname @)).png'
tree

Output

.
└── all_images
    ├── dash_1
    │   └── rgb.png
    ├── dash_2
    │   └── rgb.png
    ├── dash_3
    │   └── rgb.png
    ├── dash_4
    │   └── rgb.png
    └── dash_5
        └── rgb.png

.
└── all_images
    ├── dash_1
    │   └── dash_1.png
    ├── dash_2
    │   └── dash_2.png
    ├── dash_3
    │   └── dash_3.png
    ├── dash_4
    │   └── dash_4.png
    └── dash_5
        └── dash_5.png

6 directories, 5 files
  • Related