You are not logged in.

#1 2011-11-13 14:58:57

cypherinside
Member
Registered: 2011-04-22
Posts: 34

[Solve] Bash: Rename file in folder to sequential numbers saving path

I have a folder with many subfolders with many files. I want to rename all files to sequential numbers (0001.jpg, 0002.jpg, .0003,jpg ...) but i want to save the path. I mean that the files should not be saved in the root directory (where i launched the script), but I want them to remain in original subdirectorys. How can i do this?

Last edited by cypherinside (2011-11-14 18:37:16)


To be or not to be? ...Not to be! (Last Action Hero)

Offline

#2 2011-11-13 15:02:11

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

What script are you using? Or are you trying to write one?

Last edited by karol (2011-11-13 15:03:28)

Offline

#3 2011-11-13 15:06:59

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

#!/bin/bash

[[ $1 ]] || exit 1

for src in "$1"/*; do
  printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"
  mv "$src" "$dest"
done

Offline

#4 2011-11-13 17:29:14

cypherinside
Member
Registered: 2011-04-22
Posts: 34

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

@Karol: I'm trying to write one
@Falconindi: It doesn't works

I tried this

i=0
find -type f -iname "*.jpg" | while read x; do
    mv "${x}" "$(printf "%04d" ${i}).jpg"
    i=$((i+1))
done

and it works but all the file are moved to the root directory! I want to preserve their path.

Last edited by cypherinside (2011-11-13 19:25:49)


To be or not to be? ...Not to be! (Last Action Hero)

Offline

#5 2011-11-13 17:43:55

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,615

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

falconindy wrote:
...
for src in "$1"/*; do
  printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"
  mv "$src" "$dest"
...

Question:  I have done most of my coding in C and C++, I hack in Python.  I have learned the hard way avoid structures like that.  What is happening under-the-hood that makes it safe to modify the collection through which you are iterating?


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
The shortest way to ruin a country is to give power to demagogues.— Dionysius of Halicarnassus
---
How to Ask Questions the Smart Way

Offline

#6 2011-11-13 19:24:48

thisoldman
Member
From: Pittsburgh
Registered: 2009-04-25
Posts: 1,172

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

This worked on a test directory with a single subdirectory.  You must give it the parent directory name.  I haven't tested it thoroughly.

#!/bin/bash
# requires a parent directory name

find "$1" -depth -iname "*.jpg" | while read file ; do
    directory=$(dirname "$file")
    oldfilename=$(basename "$file")
    newfilename=$(printf "%04d" ${i}).jpg
    i=$((i+1))
    mv "$directory/$oldfilename" "$directory/$newfilename"
done
exit 0

Offline

#7 2011-11-13 19:33:26

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

ewaller wrote:
falconindy wrote:
...
for src in "$1"/*; do
  printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"
  mv "$src" "$dest"
...

Question:  I have done most of my coding in C and C++, I hack in Python.  I have learned the hard way avoid structures like that.  What is happening under-the-hood that makes it safe to modify the collection through which you are iterating?

"$1"/* isn't a collection persay. It expands to the list of matches for the glob. You're essentially making a copy of a list and then writing a new list, based on the old names.

Anyways, yeah I missed the part with about subdirectories. find works, but I'd prefer to do this still in bash:

#!/bin/bash

walk() {
  for src in "$1"/*; do
    if [[ -d $src ]]; then
      walk "$src"
      continue
    fi
    printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"
    mv "$src" "$dest"
  done
}

[[ $1 ]] || exit 1

walk "$1"

Offline

#8 2011-11-13 21:38:02

cypherinside
Member
Registered: 2011-04-22
Posts: 34

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

@thisoldman: it doesn't works (the numeration is caotic)
@falconindy: thanks it works, but i want the numbering starts with 0001 for each folder.
I did not know you could define functions in bash scripts... this is wonderful.
I understand something (but not too much) about C. Can you explain me the script?

walk() {

You have defined a function

for src in "$1"/*; do ## "$1"/*

are all the subdirectory. Can i use "$(pwd)/*" instead of "$1/*"? In this way i don't write the parent directory

if [[ -d $src ]];
      walk "$src"
      continue
    fi

I dont' understand

printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"

Stores in dest... what? I assume that %s is a string as in C language, infact you give "$1" as argument (but why?). And I assume that  "$((++i))" is like i=$((i+1)). Is it right?

mv "$src" "$dest"
  done
}

Ok

[[ $1 ]] || exit 1

I don't understand.

walk "$1"

Ok


To be or not to be? ...Not to be! (Last Action Hero)

Offline

#9 2011-11-13 21:47:04

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

cypherinside wrote:
for src in "$1"/*; do ## "$1"/*

are all the subdirectory. Can i use "$(pwd)/*" instead of "$1/*"? In this way i don't write the parent directory

If you want to specify $PWD, just call the script with an argument of '.' to point it at PWD.

cypherinside wrote:
if [[ -d $src ]];
      walk "$src"
      continue
    fi

I dont' understand

It's simple recursion. You don't want to rename directories, you want to process the contents of the directory in the same way you're processing the current directory.

cypherinside wrote:
printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"

Stores in dest... what? I assume that %s is a string as in C language, infact you give "$1" as argument (but why?). And I assume that  "$((++i))" is like i=$((i+1)). Is it right?

It's the bash equivalent of sprintf(3).

cypherinside wrote:
[[ $1 ]] || exit 1

I don't understand.

If $1 doesn't exist (i.e. you passed no arguments to the script), then refuse to run and exit immediately with an error.

You weren't really clear in your requirements, so I wrote it as I interpreted it. If you want to reset the numbering for each directory, scope 'i' locally:

#!/bin/bash

walk() {
  local -i i=0

  for src in "$1"/*; do
    if [[ -d $src ]]; then
      walk "$src"
      continue
    fi
    printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"
    mv "$src" "$dest"
  done
}

[[ $1 ]] || exit 1

walk "$1"

Offline

#10 2011-11-13 22:39:49

cypherinside
Member
Registered: 2011-04-22
Posts: 34

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

Yes, I'm sorry if I was not very clear in my question (as you may have noticed I did not express very well in English... Google translate helps me! big_smile)

falconindy wrote:

If you want to specify $PWD, just call the script with an argument of '.' to point it at PWD.

No, really I want call the script without arguments (if this is possible), because this script will be part of a bigger script that doesn't use arguments (so I must run it inside the parent directory).


To be or not to be? ...Not to be! (Last Action Hero)

Offline

#11 2011-11-13 22:41:22

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

Then remove the conditional and change the last line to:

walk "${1:-$PWD}"

Last edited by falconindy (2011-11-13 23:57:37)

Offline

#12 2011-11-13 22:50:29

cypherinside
Member
Registered: 2011-04-22
Posts: 34

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

I'm sorry if I insist but I do not want to use the script without understanding it: what's the benefit to use "$1"? Can i directly use $(pwd)?

EDIT: with walk "${1:$PWD}" it don't work. The script is executed in / directory!!! Luckily I used immediately CTRL+C... (fiuuuuu!) otherwise my home directory would be irretrievably compromised

Last edited by cypherinside (2011-11-13 23:12:03)


To be or not to be? ...Not to be! (Last Action Hero)

Offline

#13 2011-11-13 23:04:36

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

The point of the change I just mentioned is that if you do not supply an argument, the script will default to $PWD.

Yes, you can hardcode in $PWD, but I fail to see the point of doing so.

http://mywiki.wooledge.org/BashGuide

Offline

#14 2011-11-13 23:09:27

cypherinside
Member
Registered: 2011-04-22
Posts: 34

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

read the edit, please smile

Last edited by cypherinside (2011-11-13 23:18:25)


To be or not to be? ...Not to be! (Last Action Hero)

Offline

#15 2011-11-13 23:57:51

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

An unfortunate typo. Fixed.

Offline

#16 2011-11-14 18:35:19

cypherinside
Member
Registered: 2011-04-22
Posts: 34

Re: [Solve] Bash: Rename file in folder to sequential numbers saving path

Thanks for everything.


To be or not to be? ...Not to be! (Last Action Hero)

Offline

Board footer

Powered by FluxBB