1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Windows File renaming question - NEW QUERY - see post #22

Discussion in 'Software' started by Shirty, 23 Feb 2015.

  1. Shirty

    Shirty W*nker! Super Moderator

    Joined:
    18 Apr 1982
    Posts:
    12,485
    Likes Received:
    1,701
    One of my colleagues has spent days creating a bunch of files, only to be told that they all need to contain not just the text description, but also the unique code of the item in question.

    So presently the files are named:

    Product_Description_A.pdf
    Product_Description_B.pdf
    Product_Description_C.pdf
    etc.

    The files should actually be called:

    001248_Product_Description_A.pdf
    003987_Product_Description_B.pdf
    1124879_Product_Description_C.pdf
    etc.

    At present, we have a folder full of files with the incomplete filename, and a spreadsheet containing the correct filenames. Now I'm great at adding a single prefix/suffix to multiple files, there are a host of programs that will let you do that.

    What I'm wondering is whether there is any simple way to merge/replace the existing filenames with the unique prefix values using some kind of lookup?

    I suspect not, but if you don't ask you don't get.

    We are in a Windows environment, and we are talking about several thousand files. It will be arduous, although I suspect necessary, if we have to manually append each file with the correct prefix.
     
    Last edited: 20 Jun 2016
  2. Phil Rhodes

    Phil Rhodes Hypernobber

    Joined:
    27 Jul 2006
    Posts:
    1,415
    Likes Received:
    10
    This can certainly be automated.

    What I'd do is either copy-and-paste or just export the relevant parts of the spreadsheet into a text file, and write a script (my preference is javascript, but many things could do it) to read that text file, then go through the filenames existing filenames and look up the new modified filename.

    If you don't have anyone on hand who can do that, throw me a private message including (a small example of) the spreadsheet and some of the files.

    P
     
  3. faugusztin

    faugusztin I *am* the guy with two left hands

    Joined:
    11 Aug 2008
    Posts:
    6,940
    Likes Received:
    264
  4. Phil Rhodes

    Phil Rhodes Hypernobber

    Joined:
    27 Jul 2006
    Posts:
    1,415
    Likes Received:
    10
    ...which is why I wouldn't do it in powershell!
     
  5. Gareth Halfacree

    Gareth Halfacree WIIGII! Staff Administrator Super Moderator Moderator

    Joined:
    4 Dec 2007
    Posts:
    14,278
    Likes Received:
    3,135
    Okay, so yer on Windows and the advice I'm going to give you is for *NIX - but you should be able to do it on Windows by installing Cygwin. Assuming that you can install Cygwin and get a *NIX-like shell up, my advice would be the following: get your list of real filenames in a text file, one per line, called "realnames.txt." Then it's a one-liner:

    ls *pdf | xargs -I {} sh -c 'mv {} `grep {} realnames.txt`'

    That finds all pdf files (WARNING: case-sensitive on Linux, probably not case-sensitive on Cygwin) then executes a shell for each PDF that searches for the filename in your list and then moves it (mv) to the correct name. If it doesn't find a match, you'll get an error (because mv will have been called with only one of the two required filenames.)

    Dun!

    You could also do it with a "for i in *pdf" loop, but as you've got thousands xargs is the way to go as you won't suddenly run out of resources halfway through the job.

    EDIT: Proof that it works:

    [​IMG]
     
  6. Shirty

    Shirty W*nker! Super Moderator

    Joined:
    18 Apr 1982
    Posts:
    12,485
    Likes Received:
    1,701
    Very sexy responses folks, and super appreciated. I'll have a pop at this tomorrow and let y'all know how it turns out!

    Muchas gracias!
     
  7. jinq-sea

    jinq-sea 'write that down in your copy book' Super Moderator

    Joined:
    15 Oct 2012
    Posts:
    8,469
    Likes Received:
    536
    I do love this forum. It's great!

    What I would highly recommend not doing is typing:

    Code:
    chmod * 444
    It made everything go very wrong, and earned me the moniker of 'The CHMOD Kid...'
     
  8. RedFlames

    RedFlames ...is not a Belgian football team

    Joined:
    23 Apr 2009
    Posts:
    13,730
    Likes Received:
    2,161
    IIRC it is doable with powershell, but [again iirc since it's a while since I've had to do anything like that] it's a bit of a mare.

    I'd probably go with Gareth's method with cygwin [also he's gone through the effort of demonstrating it working...], as for cygwin and case sensitivity I don't think it is by default... but i haven't used it in a while so don;t hold me to that...
     
  9. Phil Rhodes

    Phil Rhodes Hypernobber

    Joined:
    27 Jul 2006
    Posts:
    1,415
    Likes Received:
    10
    Cygwin is going to make it rather complicated. I'd do it in jscript, which is already there and working.
     
  10. wolfticket

    wolfticket Downwind from the bloodhounds

    Joined:
    19 Apr 2008
    Posts:
    3,202
    Likes Received:
    369
    If you have a single sheet that contains the correct file names in order you could simply output the list to a suitably formatted text file then use a tool like Bulk Rename Utility that can batch rename files from a list in a text file.
     
  11. silk186

    silk186 Derp

    Joined:
    1 Dec 2014
    Posts:
    1,898
    Likes Received:
    147
    When I was into reading manga more I would download chapters that were named differently. I remember using batch renamers that were both free and useful. Perhaps that would help.
     
  12. Gareth Halfacree

    Gareth Halfacree WIIGII! Staff Administrator Super Moderator Moderator

    Joined:
    4 Dec 2007
    Posts:
    14,278
    Likes Received:
    3,135
    I look forward to your sharing your JavaScript file renaming code. We can compare its complexity relative to my single-line shell command - that should be interesting!
     
    Shirty likes this.
  13. Shirty

    Shirty W*nker! Super Moderator

    Joined:
    18 Apr 1982
    Posts:
    12,485
    Likes Received:
    1,701
    Gareth, your command executed flawlessly. Aside from a few manual fixes I had to make to the source data where symbols had been used in the file names, but that's to be expected with these things.

    You are a lifesaver!
     
  14. Gareth Halfacree

    Gareth Halfacree WIIGII! Staff Administrator Super Moderator Moderator

    Joined:
    4 Dec 2007
    Posts:
    14,278
    Likes Received:
    3,135
    [​IMG]
     
  15. Atomic

    Atomic Gerwaff

    Joined:
    6 May 2002
    Posts:
    9,646
    Likes Received:
    94
    Late to the party, but here's the PowerShell for the task... it's not quite as short as Gareth's code but is native to Windows.

    With "FileList.csv" containing old and new file names like so:
    Code:
    OldName,NewName
    Product_Description_A.pdf,001248_Product_Description_A.pdf
    Product_Description_B.pdf,003987_Product_Description_B.pdf
    Product_Description_C.pdf,1124879_Product_Description_C.pdf
    
    And the expanded easy to read code :
     
    Last edited: 24 Feb 2015
  16. Gareth Halfacree

    Gareth Halfacree WIIGII! Staff Administrator Super Moderator Moderator

    Joined:
    4 Dec 2007
    Posts:
    14,278
    Likes Received:
    3,135
    Interesting to see the differences betwix the two methods! For completeness, here's the *NIX shell equivalent to your PowerShell, and which does exactly the same thing: takes a CSV (realnames.csv) as input where the first field is the incorrect filename and the second field is the correct filename and renames the files accordingly:
    Code:
    xargs -I {} sh -c 'mv `echo {} | sed "s/,/\ /"`' < realnames.csv
    For those playing along at home: xargs lets you run commands multiple times from an input list; -I {} tells xargs to assign each line of its input (our CSV) to the variable named {} for use later in the command; sh -c says that for each line xargs should run a shell (sh) with the command that follows in single-quotes; mv is the first half of the move command; `echo {} | sed "s/,\ /"` runs the command located in the backticks, which pushes each line of the CSV through sed to replace the comma with a space; the final single-quote ends the command, which has at this point become mv wrongname.pdf rightname.pdf. < realnames.csv pushes the contents of realnames.csv through xargs as its input. Xargs will then run through the CSV a line at a time, renaming everything as it goes.

    You could significantly simplify this by using a space as the delimiter when exporting the CSV data, or by processing the CSV file first:

    Code:
    cat realnames.csv | sed 's/,/\ /' > realnames.txt
    Would pre-process the file, swapping all the commas for spaces and outputting it as a new file called realnames.txt, and then the renaming command would simply be:

    Code:
    xargs -n2 mv < realnames.txt
    Isn't scripting fun?
     
    Last edited: 24 Feb 2015
  17. RichCreedy

    RichCreedy Hey What Who

    Joined:
    24 Apr 2009
    Posts:
    4,699
    Likes Received:
    172
    for those who want to play with powershell, I have found a cheat sheet for you here
     
  18. Atomic

    Atomic Gerwaff

    Joined:
    6 May 2002
    Posts:
    9,646
    Likes Received:
    94
    It does slightly more than that...

    It imports the CSV into a new blank array ($FileList) using the OldName field as key (thus [] brackets):
    Then goes through each pdf file and renames only those that match an entry in the array.

    If I'm reading your code correctly (with my limited knowledge):
    Code:
    xargs -I {} sh -c 'mv `echo {} | sed "s/,/\ /"`' < realnames.csv
    I think the PS equivalent would be much simpler:
    Code:
    ipcsv ".\FileList.csv" | % {rni ".\$_.OldName" $_.NewName}
    As it reads the csv natively and doesn't need to spawn a new shell for each action. It just deals with each rename sequentially within the single pipeline.

    The simple code would raise an exception if there was not a file for each csv line entry (but would continue) which is why I prefer using an array lookup as it doesn't try the command if it doesn't match.
     
    Last edited: 24 Feb 2015
  19. Gareth Halfacree

    Gareth Halfacree WIIGII! Staff Administrator Super Moderator Moderator

    Joined:
    4 Dec 2007
    Posts:
    14,278
    Likes Received:
    3,135
    Yeah, my version would display an error but continue in the same vein; your array-based version is undeniably neater from an execution perspective.
     
  20. Atomic

    Atomic Gerwaff

    Joined:
    6 May 2002
    Posts:
    9,646
    Likes Received:
    94
    But would never run on anything non-windows unlike yours :)
     

Share This Page