Reputation: 520
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.
|
├── dish_1
│ └── rgb.png
├── dish_2
│ └── rgb.png
├── dish_3
│ └── rgb.png
├── dish_4
│ └── rgb.png
└── dish_5
└── rgb.png
|
├── 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
Upvotes: 0
Views: 320
Reputation: 8755
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'
find all_images -type f -name rgb.png
prints a list of file paths whose filename is exactly rgb.png
.
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.
dirname all_images/dash_4/rgb.png
becomes all_images/dash_4
basename all_images/dash_4
becomes dash_4
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
.
└── 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
Upvotes: 0
Reputation: 10329
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"-type f
to restrict results to only files-exedir
in every directory where you got a hit, execute the following:sh -c
shell scriptmv
move, or "rename" in this casergb.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 loopUpvotes: 3