Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

What is an efficient way to rename files in OSX/BSD from a text file for files assumed to stay in original folder, but in the format of;

/path/old file name.ext\tnew file name.ext

There may be say thousands of entries using TAB delimiter between entries.and any line delimiter used in Windows,OSX or Linux.

File names may contain any valid character including _'!?~*&^%$#@,.∑´®†¥¨ˆ¬˚∆˙©ƒ & Asian font characters

Names end with a dotted extension e.g. .xxx.

share|improve this question
    
How are "old file name" and "new file name" separated? Are those file names allowed to contain spaces? –  slhck May 20 '12 at 15:34
    
I think a reverse parse of the string might extract the end of the folder path from the last entry of "/" to a variable so it can be used in a valid syntax for BSD using mv %path/%oldname %path/%newname , so that may require some smart script parsing. I am BSD challenged at the moment. –  Tony Stewart May 20 '12 at 15:43
    
You didn't answer my question. Is there a space separating the entries? If yes, can we assume the entries themselves contain no spaces at all? If not, is there a \t between the entries, or something else to split the entries at? –  slhck May 20 '12 at 15:47
    
File names are separated with at least 1 space, but then so are words within a file name, so the only distinction is that names end with a dotted extension e.g. .xxx –  Tony Stewart May 20 '12 at 15:48
    
That's a really bad format to work with.. oh well. Is it at least one space or one space exactly? Are the extensions of the same size (i.e. three characters)? Do all files have an extension? (Sorry that I ask so much, but you gave us not a lot to work with …) –  slhck May 20 '12 at 15:54
show 6 more comments

1 Answer 1

up vote 2 down vote accepted

Updated version:

This one takes as specification:

  • Each statement on one line
  • Records are separated by a \t character.

That makes it much easier:

require 'fileutils'
File.open("input.txt", 'r').each_line do |l|
  next if l.strip.empty?
  f = l.split("\t")
  dir = File.dirname f[0]
  if File.exists? f[0]
    p "Moving #{f[0]} to #{dir}/#{f[1].strip}"
    # FileUtils.mv f[0], "#{dir}/#{f[1].strip}"
  else
    p "#{f[0]} does not exist."
  end
end

Save this as a file and call it with ruby filename.rb. It'll read from input.txt in the same directory and just move the files.

Uncomment the # FileUtils… line for it to actually move something. This should tell you if the original file can't be found.


Your original input specification was:

  • Each statement on one line
  • Records are not terminated or separated except for their extension
  • Records can contain spaces, and delimiter can be multiple spaces ("at least 1 space")

One therefore has to fall back to matching the first file extension, then interpreting this as the first argument. Then, we need to remove this part from the original line, remove beginning and trailing whitespace, and construct the mv command.

Additional assumptions:

  • All extensions have only three characters, not more, not less
  • The file names themselves don't contain a dot (otherwise this breaks)

Since you're on OS X, let's just use Ruby:

require 'fileutils'
File.open("input.txt", 'r').each_line do |l|
  next if l.strip.empty?
  old_file = l[0, l.index(/\.[a-z0-9]{3}/i) + 4]
  dir = File.dirname old_file
  new_filename = l.sub(old_file, '').lstrip.chomp
  p "Moving #{old_file} to #{dir}/#{new_filename}"
  # FileUtils.mv old_file, "#{dir}/#{new_filename}"
end
share|improve this answer
    
tony.rb:2: undefined method +' for nil:NilClass (NoMethodError) from tony.rb:1:in each_line' from tony.rb:1 –  Tony Stewart May 21 '12 at 4:37
    
@TonyStewart Some line in the input probably didn't contain \.[a-z]{3}. Try running it on a subset of lines in the input or removing empty lines. –  Lri May 21 '12 at 8:06
    
This challenge becomes even more difficult when you consider the depth of filename specs and incompatibilities across platforms but I choose to *ignore that for now.. e.g Chinese font text and RTL Language fonts –  Tony Stewart May 21 '12 at 16:30
    
nope>> ruby tony.rb tony.rb:2: undefined method +' for nil:NilClass (NoMethodError) from tony.rb:1:in each_line' << I agree it is insane. I could do it in excel using string match for file extensions using a common set of a few .xxx and last occurrence of / to denote beginning of file name.back in 3 hrs –  Tony Stewart May 21 '12 at 17:03
1  
@TonyStewart Yeah, of course it won't work if there are numbers in the extension. You have to add 0-9 there, see my updated answer. Next time, please be way more specific with your requirements, else it's hard to diagnose or even answer to begin with. Good luck! –  slhck May 22 '12 at 7:58
show 11 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.