Jump to content

Batch copy and rename

Nordek

Hi

I have this problem: I have a folder with several hundreds subfolders. In each of these there is a file abc_1.json and I need to gather all of these files into one folder. Something like abc_1(1).json, abc_1(2).json etc. would do a job.

 

I tried searching for this file in the folder and copying using normal windows and some external copying utilities (namely nice copier - created only one renamed file, and ultracopier - kept throwing errors). I would really use some utility or a code (best in C++).

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, Nordek said:

Hi

I have this problem: I have a folder with several hundreds subfolders. In each of these there is a file abc_1.json and I need to gather all of these files into one folder. Something like abc_1(1).json, abc_1(2).json etc. would do a job.

 

I tried searching for this file in the folder and copying using normal windows and some external copying utilities (namely nice copier - created only one renamed file, and ultracopier - kept throwing errors). I would really use some utility or a code (best in C++).

Do you want them all to be "abc_1(1).json" or is that what they are now and you want to change it?

 

Because if you select all the files in the folder (Ctrl+A), right-click, Rename, enter "abc_1", hit Enter, and it will automatically rename them all "abc_1(1)" to however many files you have.

Edited by The1Dickens
Fixed steps
Spoiler

CPU: Intel i7 6850K

GPU: nVidia GTX 1080Ti (ZoTaC AMP! Extreme)

Motherboard: Gigabyte X99-UltraGaming

RAM: 16GB (2x 8GB) 3000Mhz EVGA SuperSC DDR4

Case: RaidMax Delta I

PSU: ThermalTake DPS-G 750W 80+ Gold

Monitor: Samsung 32" UJ590 UHD

Keyboard: Corsair K70

Mouse: Corsair Scimitar

Audio: Logitech Z200 (desktop); Roland RH-300 (headphones)

 

Link to comment
Share on other sites

Link to post
Share on other sites

On 10/30/2019 at 11:10 PM, The1Dickens said:

Do you want them all to be "abc_1(1).json" or is that what they are now and you want to change it?

 

Because if you select all the files in the folder (Ctrl+A), right-click, Rename, enter "abc_1", hit Enter, and it will automatically rename them all "abc_1(1)" to however many files you have.

Pretty sure he wants to search through a directory tree, grab anything named 'abc_1.json, rename it with an iterator (eg., first instance to abc_1(1).json, second instance to abc_1(2).json, etc.) and copy them all to a new directory...

 

In pseudo-ps-code, something like

 

$source="C:\dir_to_search"
$destination="C:\dir_to_move_to\"
$files=@("*abc_1*.json")
$i=0
New-Item -ItemType Directory -Force -Path ($destination); Get-ChildItem -recurse ($source) -include ($files); % {Rename-item $_.Name ( $_.Name+$i)}; $i+=1 | Copy-Item -Destination ($destination) 

 

Note, to actually work, this would probably need to be split into a while loop / piping order and focus is wrong. 

Link to comment
Share on other sites

Link to post
Share on other sites

If you want a single time job, download Total Commander : https://www.ghisler.com/download.htm

 

Go in the base folder, press Alt+F7 or go in Commands menu, then Search option (same thing)

Search for all files, or type *.json for example to get only json files.

Select to search in sub-folders and check other things (like for example you can say how many folders deep to go from base folder)

When done, click on the "Feed to listbox" and you'll get all the files on one side of Total Commander.

You can select all files by pressing on the * key on numeric pad, or you can select only some files with the + on numeric pad (or you can use the Mark menu)

Browse to where you want to copy the files in the opposite panel, then click on the Copy button on the bottom or press its shortcut, F5

When a file would overwrite a previous one, Total Commander will ask if you want to overwrite and one of the options will be to auto-rename incoming files the way you want. It will do it automatically for the rest if you so choose.

 

If you want a script, it can be done in PHP within a few minutes.

Generate a list of the files you want with the DIR command.

Open a command prompt in the base folder by holding Shift as you right click in an empty area outside the file list in Windows Explorer in that folder. If you hold Shift as you right click, you should get a "Open command prompt here" option

Type

 

DIR *.json /B /S /A:-D >C:\temp\filelist.txt

 

DIR - list contents of folder

*.json  - limit results to file names that have the json extension

/B - bare format, show one file name with its path on one line

/S - list contents of folder, then go through sub folders.

/A:-D - add or exclude files or folders with the attributes (-D means exclude folders from listing, as you want only files)

> - redirect output from screen into the file name that follows (try to avoid spaces, hence why I used c:\temp)

 

Now you can write a script that reads the file names from the text file,  splits each file name into path , name and extension and creates the BAT file for you, which will copy stuff when you run it.

 

You have the code below.  You can paste this in Notepad, edit the 3 parameters at the top, then save the file with the php extension. Save as, save as type : all files,  type a name and put ".php" as extension.

Then download PHP for Windows from here, doesn't matter which version : https://windows.php.net/download#php-7.3 

 

This version would work just fine: https://windows.php.net/downloads/releases/php-7.3.11-nts-Win32-VC15-x64.zip

You may or may not need the Visual C runtimes (if you get an error running the script, download and run this) : https://aka.ms/vs/16/release/VC_redist.x64.exe

 

Copy the php file you just saved in the same folder where php.exe is, open a command prompt in this folder as I explained above, and type  php.exe  your_script_name.php and php will run the script and the script will generate the BAT file, which you can then launch and it will copy the files to your desired folder.

 

<?php

// Use / instead of \ , it's better and Windows doesn't mind.

$inputFile = 'c:/temp/filelist.txt';
$outputFile = 'c:/temp/copy.bat';

// where to copy files 

$copyDestination = 'c:/temp/destination/';

// --- nothing to edit below ---

$outputText = "";   // this will hold the text that will be written in the batch file
$fileNames = array(); // a counter for each unique file name

// extra error checking in case you don't enter destination folder correctly
$copyDestination .= '/';
$copyDestination = str_replace(array('//','/'),'\\',$copyDestination);

$content = file_get_contents($inputFile); // read filelist in memory
$lines = explode(chr(0x0D).chr(0x0A),$content); // split into lines and put in $lines array
foreach ($lines as $line) {
    if (trim($line)!='') { // is it really a path or some empty line? 
        $fileParts = pathinfo($line); // split path into folder, name, extension 
        $filename = $fileParts['basename']; // put just the name in a separate variable
        // basename = name + . + extension 
        $counter = 0;
        // did we see this filename before?
        if (isset($fileNames[$filename])==false) { // no, this is first time, remember it
            $fileNames[$filename] = 0;
        } else { // yes, add 1 to see we can have (1), (2) and so on on following files
            $fileNames[$filename]++; // adds 1;
            $counter = $fileNames[$filename]; // put the value in the counter variable.
        }
        // now let's add the copy command to the batch file.
        //
        // COPY "X:\path\filename.extension" "x:\another\path\filename.extension"
        // 
        // so we have to add the quote characters
        $outputText .= 'COPY "'.$line.'" "'.$copyDestination.$fileParts['filename'];
        // add only if needed, otherwise leave file name intact
        if ($counter>0) $outputText .= '('.$counter.')';  
        // now append extension and close the quotes, and type an ENTER
        $outputText .= '.'.$fileParts['extension'].'"';
        $outputText .= chr(0x0D).chr(0x0A); // the ENTER key is 2 characters, CR and LF
        // go to next file and do the same until you're done with the set of files
    }
}
// now the contents of the BAT file is in outputText variable, so save it to disk
$result = file_put_contents($outputFile,$outputText);
echo "Done. Batch file created.";
sleep(5);  // do nothing for 5 seconds, so you'll see the message on screen. 

?>

 

 

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

Thank you for feedback.

I tried the Total Commander before and for whatever reason couldn't copy all of the files the way I wanted to. Now it worked, thanks!

For now this method is okay but eventually I want to integrate this process into my program (in C++) so I'll keep you updated or post about problems encountered.

 

Wish me luck!

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×