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 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 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'
find all_images -type f -name rgb.png
prints a list of file paths whose filename is exactlyrgb.png
.xargs -P0 -I@ CMD...
executesCMD
in a parallel mode with@
replaced by path names fromfind
command. Please refer toman 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
becomesall_images/dash_4
basename all_images/dash_4
becomesdash_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