This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to automatically process file/dir names?


Hello,

Most of what you want in terms of the name transformations you want can be effected with the "tr" command. Study it.

Naturally, the "mv" command is how you rename files. Given the new name for a file, you'll have to do this in a multi-step fashion, at least in general. The general algorithm I'd use is something like this:

For each file to be renamed
- Create new name
- Compare new name with old one--if identical, go on to next file
- Rename ("mv") target to an intermediate name
- Rename the intermediately named file to the target name


The reason for the intermediate name is to accommodate cases where only alphabetic case is changing. Cygwin "mv" fails in this case.

Hmmm... I'm sure Cygwin _used to_ fail in this case, but it seems to have been improved (would you guys stop that?!). You'll still need the "-f" option (which would not be the case in any fully case-sensitive file system) and I cannot tell you at which Cygwin release this issue was resolved (and whether the change that fixed it is in the Cygwin1.dll "kernel" or in the fileutils or both), so I cannot assure you that your Cygwin installation will handle a file rename that only changes case unless you're running all the latest Cygwin packages.


To apply this transformation throughout a directory hierarchy, you should probably use the "find" command (*). If you have only a few files, you can write a script to do the renaming on a single-file basis and use something like "find <targetDir> -type f -exec renamingScript {} \;". However, if you have many files to process, the overhead of running a script for each file might be excessive. In that case, I'd probably write the script to take a directory name and to iterate over the files in that directory. Then you'd invoke it "find <targetDir> -type d -exec renamingScript {} \;".

This sort of construct will allow your script (I'm assuming BASH) to enumerate the files in a directory, given that directory's name:

# Target directory is specified in argument 1
targetDir="$1"

for targetFile in "$targetDir"/*; do
if [ ! -f "$targetFile" ]; then
continue
fi

# Apply the file name changes here
done

(*) Given this outline, you can see how you'd skip using "find" to traverse a directory hierarchy. You can use the "test" / "[" command's "-d" option to detect directories and recursively invoke your script to process that directory's contents.

Lastly note that this outline omits considerations of less likely but far from impossible complications like lack of permissions, presence of directory entries other than files or directories, etc and general error checking.

I hope this is enough information to get you going.

Oh, yeah. Barely any (possibly none) of this is Cygwin-specific.

Randall Schulz



At 03:02 2003-01-18, svartsjel@gmx.net wrote:
Hi,

Quite a few problems arise from within self-written scripts when dealing with (Windows') file and directory names containing spaces. I therefore thought about a script which takes a directory as argument, recursively processing both file and (sub)dir names in it (starting with the argument's name itself), replacing each space with an underscore (additionally also rendering everything lowercase), and cutting off trailing space(s) from names, respectively. For instance, the processed files fortunes-o_, index_2.htm_ and index2_.html should be detected and fixed like this: fortunes-o, index_2.htm, index2.html.

How would you accomplish that?

Many thanks in advance, and best wishes!

svartsjel

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]