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_imageswill start looking from the directory "/all_images"-name rbg.pngwill look anywhere for anything named "rbg.png"- optionally use
-type fto restrict results to only files -exedirin every directory where you got a hit, execute the following:sh -cshell scriptmvmove, or "rename" in this casergb.pngfile named "rgb.png"$(basename $PWD).pngoutput 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.pngprints a list of file paths whose filename is exactlyrgb.png.xargs -P0 -I@ CMD...executesCMDin a parallel mode with@replaced by path names fromfindcommand. Please refer toman xargsfor 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.pngbecomesall_images/dash_4basename all_images/dash_4becomesdash_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
