LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-03-2008, 12:00 PM   #1
fsckin
LQ Newbie
 
Registered: Oct 2008
Posts: 3

Rep: Reputation: 0
Directory Traverse & Rename Script


I am running this script in cygwin, but since I found the original here, I figured it would be OK to post here.

I'm using this to extract the contents of a version control system folder dump into something usable. It was previously gziped up (eg 1.1.gz) but that's been fixed.

The way my modified script works now, it runs through all subdirectories and properly renames files with names like "1.1" and changes them to be foldername.ext, which is perfect. It also has the bonus of overwriting a 1.1 file with a 1.2 file (which happens to be a newer version) which is also the behavior I want.

What isn't perfect is when it does something I don't want, like this:
mv PATH\fileone.ext PATH.ext

fileone.ext will NEVER start with "1" and I'd like to stop the script from performing any commands on a file that begins with "1"

Here's the directory structure
Code:
C:\PATH

C:\PATH\fileone.ext
C:\PATH\filetwo.ext
C:\PATH\filethree.ext

C:\PATH\folder1,d\
-----------------\1.1
-----------------\1.2

C:\PATH\folder2,d\
-----------------\1.1
-----------------\1.2
-----------------\1.3

C:\PATH\folder3,d\
-----------------\1.1
-----------------\1.2
-----------------\1.3

C:\PATH\folder4,d\subdirectory1\
------------------------------\filefour.ext
------------------------------\filefive.ext
------------------------------\filesix.ext

C:\PATH\folder5,d\subdirectory2,d\
------------------------------\1.1
------------------------------\1.2
------------------------------\1.3



Code:
#!/bin/bash
while read file
do
  basename=${file##*/}
  if [ $(expr index "$basename" .) -gt 0 ]
  then
    extension=.${file##*.}
  else
    extension=""
  fi
  dirname=${file%/*}
  newname=${dirname##*/}
  newname=`echo "$newname$extension" | cut -d',' -f1`
  echo mv "$file" "$dirname/$newname"
done < <(find FOLDERPATH -type f)



-Wayne
 
Old 10-04-2008, 03:42 PM   #2
zmanea
Member
 
Registered: Sep 2003
Location: Colorado
Posts: 85

Rep: Reputation: 15
First you say that you want it to process files that start with a 1

Quote:
it runs through all subdirectories and properly renames files with names like "1.1" and changes them to be foldername.ext, which is perfect. It also has the bonus of overwriting a 1.1 file with a 1.2 file (which happens to be a newer version) which is also the behavior I want.
Then you say that you dont?

Quote:
fileone.ext will NEVER start with "1" and I'd like to stop the script from performing any commands on a file that begins with "1"
It is hard to give an exact example without understanding what you are trying to do. There are a couple of ways to filter out files with what you are doing, you can start by changing your find command. Something like the following:

find -type f -name "[!1]*"
 
Old 10-04-2008, 05:21 PM   #3
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
Cygwin will access the C:\ drive like "/cygdrive/c/". It would help if you posted a segment from the results of a find command so we can see what it looks like exactly. Then describe the "after" better with an example.

Also, it appears that FOLDERPATH is supposed to be replaced with the base directory to start the search. You are taking it literally.

I would suggest adding a line in the top like "FOLDERPATH=/cygdrive/c/projects" and then changing the last line to "done < <(find "$FOLDERPATH" -type f)". This will use a variable in the last line which is defined before the loop starts.

Code:
 echo mv "$file" "$dirname/$newname"
This is a good idea. Inserting an echo allows you to debug the script before doing anything destructive. You might want to redirect the output to a file if there is a large number of files.

Is the index command a bash function, which you haven't posted? There is a C library function index() which returns a pointer to the first instance of a character in a string.

You might consider writing your own function that checks for a (.[[:digit:]]+)+ pattern at the end of a string. Look at the "=~" conditional operator.

Last edited by jschiwal; 10-04-2008 at 05:39 PM.
 
Old 10-05-2008, 01:43 AM   #4
fsckin
LQ Newbie
 
Registered: Oct 2008
Posts: 3

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by zmanea View Post
find -type f -name "[!1]*"
That's pretty damn smart.

I did get it functional, but ran into the ugly beast of spaces in the filename. So I echoed all commands into a file, which I piped into bash. Worked well. I ended up doing this in two parts, and the old version of my script was overwritten... anywho 80,000 files later it ran into problems with "too long of filename", but that was with files that were in nested folders 30 deep.



Here's what it eventually ended up like, I'm pretty damn sure this is NOT optimal with the grep and cut commands, but it did the job.

Code:
#!/bin/bash
while read file
do
  basename=${file##*/}
  if [ $(expr index "$basename" .) -gt 0 ]
  then
    extension=.${file##*.}
  else
    extension=""
  fi
  dirname=${file%/*}
  newname=${dirname##*/}
  newname=`echo "$newname$extension" | cut -d',' -f1`
if echo "$dirname" | grep -q ,d""
then
  newlocation=`echo "$dirname" | cut -d',' -f1`
  echo "mv \"$dirname/$newname\" \"$newlocation\""
  echo "rm -r \"$dirname\""
fi
done < <(find FOLDER -type f)
Here's an example of how I should have done it:

Code:
mv "Base/Sub/Test File Name.ext,d/1.1" "Base/Sub/Test File Name.ext"
rm -r "Base/Sub/Test File Name.ext,d/"
I might figure out something more elegant, but this should be a one time process. I wont ever need to go back to the old way things were compressed and in weird folder names, etc.
 
  


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
To rename files in a directory should I use Bash script or a Perl Script ? jamtech Programming 7 01-22-2008 11:25 PM
bash: make rename script traverse directories morrolan Programming 2 11-08-2006 10:52 AM
Bash script to traverse directory tree and rename files intramaweb Programming 3 10-08-2006 12:51 PM
Script tar+gzip traverse a directory gn00kie Programming 7 06-16-2006 01:52 AM
is there a way to traverse a directory structure & execute a command hemlock Linux - Newbie 1 09-07-2002 12:22 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:54 PM.

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