Utility to rename files as they are extracted from a RAR archive
June 16, 2014 3:48 AM Subscribe
I have many data files named in a particular format. The files are either ZIP or RAR archives, and contain several sub-data files each in different formats (with a different extension; this is Windows). I need a utility to extract the contents and simultaneously rename each sub-data file to the name of its parent archive AND preserve the sub-data files' extensions. Anyone know of such a utility? Winrar, 7zip don't do this, and I've had no luck searching around.
Response by poster: The names are similar to:
satellite_date_experiment_someID.rar
the contents of the RAR file are similar to:
observation1.txt
obs2.csv
observed_data_3.asc
...and possibly others.
I just want everything in one folder with no archives!
....I can feel some scripting coming on, but just wondered if there's already a pre-canned solution.
posted by flutable at 4:00 AM on June 16, 2014
satellite_date_experiment_someID.rar
the contents of the RAR file are similar to:
observation1.txt
obs2.csv
observed_data_3.asc
...and possibly others.
I just want everything in one folder with no archives!
....I can feel some scripting coming on, but just wondered if there's already a pre-canned solution.
posted by flutable at 4:00 AM on June 16, 2014
Best answer: So from the file satellite_date_experiment_someID.rar you want:
observation1.txt -> satellite_date_experiment_someID.txt
obs2.csv -> satellite_date_experiment_someID.csv
observed_data_3.asc -> satellite_date_experiment_someID.asc
Is this right?
This wouldn't take long to do in bash (Linux), I don't know of a pre-canned solution for Windows, sorry.
posted by devnull at 4:07 AM on June 16, 2014
observation1.txt -> satellite_date_experiment_someID.txt
obs2.csv -> satellite_date_experiment_someID.csv
observed_data_3.asc -> satellite_date_experiment_someID.asc
Is this right?
This wouldn't take long to do in bash (Linux), I don't know of a pre-canned solution for Windows, sorry.
posted by devnull at 4:07 AM on June 16, 2014
You can do this with powershell - this page has an example of unraring all files in a folder.
In your case you would have to unpack the files to a temporary folder, unrar (or unzip) the files, then traverse through the files in the temporary folder (this would be another foreach inside the foreach in the link above), then rename each of them before moving them all to the target folder.
posted by Baron Humbert von Gikkingen at 6:10 AM on June 16, 2014
In your case you would have to unpack the files to a temporary folder, unrar (or unzip) the files, then traverse through the files in the temporary folder (this would be another foreach inside the foreach in the link above), then rename each of them before moving them all to the target folder.
posted by Baron Humbert von Gikkingen at 6:10 AM on June 16, 2014
DropIt looks like you could setup with a monitored folder to do this. Here's the wiki.
(Originally came to mention these two utilities, which I'll put here for completeness, but I think DropIt will do what you need.)
-Rename Master is a free bulk-renamer, but it won't do the extraction.
-Total Commander (shareware, 1 month trial) can extract, and has a configurable 'Bulk Rename Tool', but I don't think you can tell it to do both in order.
posted by quinndexter at 6:54 AM on June 16, 2014
(Originally came to mention these two utilities, which I'll put here for completeness, but I think DropIt will do what you need.)
-Rename Master is a free bulk-renamer, but it won't do the extraction.
-Total Commander (shareware, 1 month trial) can extract, and has a configurable 'Bulk Rename Tool', but I don't think you can tell it to do both in order.
posted by quinndexter at 6:54 AM on June 16, 2014
Paste the following into extract-all.cmd:
posted by flabdablet at 7:32 AM on June 16, 2014 [1 favorite]
set work=%temp%\%random%%random%%random%%random% mkdir "%work%" || goto :eof for %%A in (*.zip *.rar) do ( "%ProgramFiles%\7-Zip\7z.exe" e -o"%work%" "%%~A" for %%F in ("%work%\*") do move "%%~F" "%%~nA%%~xF" ) rmdir "%work%"Install 7-Zip. Put extract-all.cmd in a folder along with copies of all the compressed files you want to extract, and double-click it.
posted by flabdablet at 7:32 AM on June 16, 2014 [1 favorite]
Explanation:
%temp% is a preset environment variable that identifies your Windows temporary folder. %random% is a special environment variable that expands to a new random number between 0 and 32727 each time. So set work=%temp%\%random%%random%%random%%random% means that %work% will expand to the name of a subfolder of your Windows temporary folder that has an extremely high chance of not already existing.
mkdir "%work%" attempts to create that folder, and || goto :eof aborts the script if that attempt fails (which it will do if another folder or file with that name does happen to exist). So if the mkdir succeeds, we now have a guaranteed-empty work folder.
"%ProgramFiles%\7-Zip\7z.exe" e -o"%work%" "%%~A" tells 7-Zip to extract every file from the compressed archive %%A into the output folder "%work%" (the empty one we just made earlier). The e subcommand tells 7-Zip to stick all the extracted files straight into the output folder, ignoring any internal folder hierarchy the compressed archive might have. Using "%%~A" instead of the bare %%A guarantees that the compressed archive's own expanded filename will be wrapped in one set of quotes, just in case its name includes spaces.
for %%F in ("%work%\*") do stuff does stuff repeatedly, once for each file in the %work% folder. Since that folder is now occupied exclusively by whatever got extracted from the compressed archive, it will do stuff once for each extracted file, making %%F expand to the file's full pathname (because %work% is a full pathname).
move "%%~F" "%%~nA%%~xF" moves the file %%F out of the work folder and into the current folder, with a name consisting of the current archive file's name without its extension (this is what %%~nA expands to) followed by the extracted file's existing extension (which is what %%~xF expands to).
Because the for %%F command repeats that move for every single file in the work folder, the work folder ends up empty again after that for is complete, ready to receive the extracted files from the next go around the for %%A loop.
Finally, rmdir "%work%" gets rid of the now-empty work folder.
posted by flabdablet at 8:06 AM on June 16, 2014
%temp% is a preset environment variable that identifies your Windows temporary folder. %random% is a special environment variable that expands to a new random number between 0 and 32727 each time. So set work=%temp%\%random%%random%%random%%random% means that %work% will expand to the name of a subfolder of your Windows temporary folder that has an extremely high chance of not already existing.
mkdir "%work%" attempts to create that folder, and || goto :eof aborts the script if that attempt fails (which it will do if another folder or file with that name does happen to exist). So if the mkdir succeeds, we now have a guaranteed-empty work folder.
for %%A in (*.zip *.rar) do ( stuff )does stuff repeatedly, once for each file in the current folder whose name matches anything.zip or anything.rar; between the parentheses, %%A will expand to the name of each such file in turn.
"%ProgramFiles%\7-Zip\7z.exe" e -o"%work%" "%%~A" tells 7-Zip to extract every file from the compressed archive %%A into the output folder "%work%" (the empty one we just made earlier). The e subcommand tells 7-Zip to stick all the extracted files straight into the output folder, ignoring any internal folder hierarchy the compressed archive might have. Using "%%~A" instead of the bare %%A guarantees that the compressed archive's own expanded filename will be wrapped in one set of quotes, just in case its name includes spaces.
for %%F in ("%work%\*") do stuff does stuff repeatedly, once for each file in the %work% folder. Since that folder is now occupied exclusively by whatever got extracted from the compressed archive, it will do stuff once for each extracted file, making %%F expand to the file's full pathname (because %work% is a full pathname).
move "%%~F" "%%~nA%%~xF" moves the file %%F out of the work folder and into the current folder, with a name consisting of the current archive file's name without its extension (this is what %%~nA expands to) followed by the extracted file's existing extension (which is what %%~xF expands to).
Because the for %%F command repeats that move for every single file in the work folder, the work folder ends up empty again after that for is complete, ready to receive the extracted files from the next go around the for %%A loop.
Finally, rmdir "%work%" gets rid of the now-empty work folder.
posted by flabdablet at 8:06 AM on June 16, 2014
For comparison purposes, the same thing in bash:
posted by flabdablet at 8:26 AM on June 16, 2014
if work=$(mktemp -d) then for archive in *.zip *.rar do 7z e -o"$work" "$archive" for file in "$work/"* do mv "$file" "${archive%.*}.${file##*.}" done done rmdir "$work" fiMain difference with the bash version is that just looking at it I'm quite confident that it will work, even without testing; getting all the quoting and special-case syntax right in a cmd script requires lots of testing (which I've done, by the way - the cmd script above does work).
posted by flabdablet at 8:26 AM on June 16, 2014
Just had a look at DropIt, and as a crusty old greybeard it gave me a bit of a giggle. Those crazy kids have gone to a huge amount of trouble to create an even less useful scripting language than cmd, and with a very bizarre script editor to boot. I fail to see how cmd or powershell or vbs are any harder to learn than their rules-and-actions thing for the kinds of task that DropIt looks useful for, and time spent doing so opens up many more possibilities than DropIt offers.
If you write a cmd script (or a js script or vbs script or indeed any program at all), and drag and drop any file or folder onto your script's launch icon (be that the icon for the actual script, or for a shortcut to that script) then Windows will pass the pathnames of the items you dragged and dropped as script arguments.
So if you want the ability to expand new archive files as you acquire them, as well as the ability to batch-process a bunch of existing archives, modify expand-all.cmd as follows:
If you're using expand-all.cmd directly, the current folder will be the one that expand-all.cmd itself is in. If you're using it via a shortcut, you can make the current folder anything you like by setting the "Start in" item in the shortcut's properties.
posted by flabdablet at 9:44 PM on June 16, 2014
If you write a cmd script (or a js script or vbs script or indeed any program at all), and drag and drop any file or folder onto your script's launch icon (be that the icon for the actual script, or for a shortcut to that script) then Windows will pass the pathnames of the items you dragged and dropped as script arguments.
So if you want the ability to expand new archive files as you acquire them, as well as the ability to batch-process a bunch of existing archives, modify expand-all.cmd as follows:
set work=%temp%\%random%-%random%-%random%-%random% mkdir "%work%" || goto :eof set archives=%* if not defined archives set archives=*.zip *.rar for %%A in (%archives%) do ( "%ProgramFiles%\7-Zip\7z.exe" e -o"%work%" "%%~A" for %%F in ("%work%\*") do move "%%~F" "%%~nA%%~xF" ) rmdir "%work%"%* expands to all the script's arguments, so %archives% will expand to the names of all the files you drop onto the script, or to *.zip *.rar if you don't drop any. So if you just double-click expand-all.cmd's icon, it will work exactly as it did before and expand all the zip and rar files in the current folder. If you drag an archive file (or a multi-selected group of archive files) and drop onto expand-all.cmd's icon, it will expand those into the current folder instead.
If you're using expand-all.cmd directly, the current folder will be the one that expand-all.cmd itself is in. If you're using it via a shortcut, you can make the current folder anything you like by setting the "Start in" item in the shortcut's properties.
posted by flabdablet at 9:44 PM on June 16, 2014
Also for comparison, a bash script with the same capability:
posted by flabdablet at 9:55 PM on June 16, 2014
if work=$(mktemp -d) then test -n "$1" && set -- *.zip *.rar for archive do 7z e -o"$work" "$archive" for file in "$work/"* do mv "$file" "${archive%.*}.${file##*.}" done done rmdir "$work" fi
posted by flabdablet at 9:55 PM on June 16, 2014
This thread is closed to new comments.
posted by devnull at 3:50 AM on June 16, 2014