LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 11-07-2021, 01:29 AM   #1
sofasurfer
Member
 
Registered: Oct 2003
Posts: 252

Rep: Reputation: 20
How can I rename files in recursive folders and the move the files all to one directory?


I have 100 directories which are full of photos. There are also sub directories full of photos. I want to rename all photos with a number (example 1-10000) prefixed onto the current filename. Then I want all photos moved into one directory.
I tried krename and after I figured out its idiosyncrasies I found that it does not dig down into the recursive directories, unless I just haven't used it properly.
I can add directories into krename and it will process the files in it but if there is a sub directory in the directory it will not process the file in it.
Is there a solution here or a better software?
I managed to rename files in a directory with a command line script but when it comes to multiple directories and recursive directories its just too complicated for me at this time.
 
Old 11-07-2021, 02:24 AM   #2
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,358
Blog Entries: 3

Rep: Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767
You can use the perl version of the rename utility for that. See "man perlre"

Code:
rename -v -n '$a=sprintf("%05d",++$a); s/^/$a."-"/ex; s/old/new/g;' **/*/*.jpeg

# or 

find ./Pictures/ -type f \( -iname '*.jpeg' -o -iname '*.jpg' -o -iname '*.raw' \) \
        -exec rename -v -n '$a=sprintf("%05d",++$a); s/^/$a."-"/ex; s/old/new/g;' {} +
Leave the -n there until it is displaying the result you want. The ** method requires globstar or the equivalent in your shell. Bash supports that, but not all the others do.

Then

Code:
find ./Pictures/ -type f \( -iname '*.jpeg' -o -iname '*.jpg' -o -iname '*.raw' \) \
        -print

find ./Pictures/ -type f \( -iname '*.jpeg' -o -iname '*.jpg' -o -iname '*.raw' \) \
        -exec mv -i -t /path/to/destination/ "{}" \;
Or at least that's how I would approach it.
 
Old 11-07-2021, 04:06 AM   #3
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,152

Rep: Reputation: 4125Reputation: 4125Reputation: 4125Reputation: 4125Reputation: 4125Reputation: 4125Reputation: 4125Reputation: 4125Reputation: 4125Reputation: 4125Reputation: 4125
Stated another way - there are lots of opportunities to screw-up. See my sigline.

Scripting is the way to go, but you need to do all the sensible checks beforehand as demonstrated above.
 
1 members found this post helpful.
Old 11-07-2021, 04:49 AM   #4
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219
Code:
find ./Pictures -type f \( -iname '*.jpeg' -o -iname '*.jpg' -o -iname '*.raw' \) |
(
n=1
while IFS= read -r fn
do
  # newfn=/path/to/destination/${n}-${fn##*/}
  newfn=/path/to/destination/$(printf "%05d" $n)-${fn##*/}
  echo mv -vi "$fn" "$newfn"
  n=$((n+1))
done
)
This won't overflow if there were too many files.
Remove the echo if it looks good.
 
Old 11-07-2021, 05:10 AM   #5
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,358
Blog Entries: 3

Rep: Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767
Quote:
Originally Posted by MadeInGermany View Post
This won't overflow if there were too many files.
Good point, though I am always skeptical of changes to $IFS. I thought about the overflow problem but the method above seems to work with at least 30,004 files. How can the upper limit be estimated without a lot of fiddling?
 
Old 11-07-2021, 08:41 AM   #6
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware64-15.0
Posts: 6,382

Rep: Reputation: 2761Reputation: 2761Reputation: 2761Reputation: 2761Reputation: 2761Reputation: 2761Reputation: 2761Reputation: 2761Reputation: 2761Reputation: 2761Reputation: 2761
A bash solution.
Code:
#!/bin/bash

shopt -s globstar
topdir=$HOME
outputdir="/tmp"
p="0000"
i=1

cd $topdir
for f in **/*.{jpg,jpeg,raw}; do
 q=$p$i
 echo mv "$f $outputdir/${q: -5}${f##*/}"
 ((i++))
done
Remove the echo if it looks good.

On my system, the output of 'getconf ARG_MAX' is 2097152.

Last edited by allend; 11-07-2021 at 08:45 AM.
 
Old 11-07-2021, 10:17 AM   #7
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219
Suggestion for the loop body:
Code:
 printf -v q "%05d" $((i++))
 echo mv "$f" "$outputdir/${q}-${f##*/}"
 
Old 11-07-2021, 11:55 AM   #8
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,627

Rep: Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556

If you have raw files with sidecar JPEGs, you need to keep the names matching - any script which simply loops and increments a counter doesn't do that.

To avoid collisions I use exiv2 to rename with the capture datetime prefixed to the existing name - unless you shoot with two cameras at the same time, that'll give you unique names without losing sidecar associations. (If you do concurrently use two cameras, you can probably get serial number from EXIF/IPTC to solve that.)

 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] I am trying to write a very simple recursive bash script to chmod 644 all files and chmod 755 all directories in a given directory Astral Axiom Programming 23 05-31-2019 07:44 AM
Samba permissions - randomly unable to rename move or save files and folders rebelscum1 Linux - Server 0 08-22-2013 05:44 PM
[SOLVED] Rename all folders in a directory to lowercase? Squerl101 Linux - Software 2 06-23-2013 09:21 AM
recursive rename of folders BreezyBadger Linux - Newbie 3 06-14-2012 06:08 PM
bash script to create folders including making recursive folders.... linux-bandit Linux - Software 8 11-28-2009 01:50 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 09:36 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration