I have a folder structure that looks like
P0
-SD1
--D
--D_2
--D_3
--D2
--D3
-SD2
--D
--D_2
--D_3
--D2
--D3
and so on.
This is the same for ~60 folders (P0~P59). So a full path might look like P02/SD3/D2/FILES
I need to copy the contents of the directories D2 and D_2 to a destination folder, keeping the folder structure of at least P*/SD*/.
Robocopy and xcopy don't seem to work with wildcards, so robocopy *\*\D2\*.* DESTINATION\FOLDER or SOURCE\DIR DEST\DIR D2\*.* don't work. It says that whatever argument contains * (i.e. #1 or #3) are invalid.
dir /ad /b D2 /s works in that it does list all directories I would like to have copied, but I can't seem to get further than that.
Unfortunately I can not use anything other than the windows command line on this machine.
If someone knows how to do this efficiently I would really appreciate the help.
I am writing a batch script that does a myriad of things. The one part I am stuck on is copying files/file structure from a location to my final image. The file structure looks something like this
Foo
|->Bar
| |->Snafu
| | |-><FILES>
| |-><FILES>
|->Bar2
| |->Snafu
| | |-><FILES>
| |-><FILES>
|->Bar3
| |->Snafu
| | |-><FILES>
| |-><FILES>
etc...
I want to copy the whole contents of the Folder Foo while maintaining the file structure. Here is the rub...this has to be able to run on a clean copy of Windows, so I cannot use any third party programs (which leaves out XCOPY, etc.).
I have tried using the "copy" command with various parameters, but the closest I get is getting the files with no folder structure. I am not always sure what is in the folders, so I can't even hard code it.
I would appreciate any help. Thanks!
You can use XCOPY, which is way better than COPY.
XCOPY is NOT a third party command, there's no need for software. It was added back in 1986 (MS-DOS 3.30, correct me if I'm wrong), so every Windows OS has it.
Command would be: xcopy /y /h /i /e foo bar
Which will:
Copy all directories structure, including empty directories (/e)
It won't prompt for confirmation
Hidden files will be also copied.
I have recently used iCloud for Windows (10) to download all pictures from iCloud onto my local machine. I then wanted to create a backup so I copy-pasted all (15'000) pictures onto an external hard disk.
I noticed that because of the copy-paste action, the "Date Created" has -- in hindsight obviously -- been changed from the date that the picture was taken to the date / time of the copy action.
Since the copy-action and before I noticed the change of date, I have put many hours into putting pictures in subfolders, etc. I would now like to put the original date/time back into the metadata.
My idea is to make a dirlisting of the iCloud original archive, returning filename, md5 hash, and Date Created. I then want to write a script (Powershell?) to find the matching file in my subfolders, and update the date.
A few questions:
Does this seem like the best approach?
Is there a better way to copy photo's in the future, keeping the original Date Created?
Any help into the right direction whether this is a good idea with Powershell, would be greatly appreciated.
Manually changing timestamps using PowerShell
To change the Date Created, Date Modified, and Date Accessed file properties using PowerShell, I'd recommend checking out this website here. It explains how to change the Date Created/Modified/Accessed file properties for a single file, for all files in a given folder, or even for a folder itself. For example:
For a single file:
To set the date created time for "filename.txt" to 5 December 2012 at, say, 9:57:05 PM, you'd write:
(Get-Item "C:\Users\Path_to_file\filename.txt").creationtime=$(Get-Date "05/12/2012 21:57:05")
Similarly, to set the date modified, you'd write:
(Get-Item "C:\Users\Path_to_file\filename.txt").lastwritetime=$(Get-Date "05/12/2012 21:57:05")
and for date accessed time:
(Get-Item "C:\Users\Path_to_file\filename.txt").lastaccesstime=$(Get-Date "05/12/2012 21:57:05")
You can event set properties to other properties. For example:
To set the date created equal to the date modified, you'd write:
(Get-Item "C:\Users\Path_to_file\filename.txt").creationtime=$(Get-Item "C:\Users\Path_to_file\filename.txt").lastwritetime
For all files in a folder named "Test":
Get-ChildItem -force 'C:\Users\Path_to_folder\Test\' * | ForEach-Object{$_.CreationTime = ("3 August 2019 17:00:00")}
Get-ChildItem -force 'C:\Users\Path_to_folder\Test\' * | ForEach-Object{$_.LastWriteTime = ("3 August 2019 17:10:00")}
Get-ChildItem -force 'C:\Users\Path_to_folder\Test\' * | ForEach-Object{$_.LastAccessTime = ("3 August 2019 17:10:00")}
Note that the -force parameter ensures that hidden files are also included. Also, keep in mind that if you want to change each picture's timestamps to that of its own corresponding image (i.e, if you want to intelligently automate the process), you'll need to write a script that takes care of each separate case.
Copy files while preserving timestamps (and more)
The simplest tool to use is Windows' own, built-in tool: robocopy. See Microsoft's documentation on the robocopy command here. You just run the program via the command prompt (with administrator privileges).
For your needs, suppose you have images and videos in their original form (the ones that have all the correct timestamps, etc.) in the folder "Original", located at "C:\Users\Person\Desktop\Original", and you'd like to copy all those images and videos to a folder located on your external hard drive, at "D:\Pictures\Copied". The following command would probably work best:
robocopy "C:\Users\Person\Desktop\Original" "D:\Pictures\Copied" *.* /e /copy:DAT /dcopy:DAT /mt:16 /j /xjd /xa:s /r:1 /w:0 /log:"filename_path.txt"
Each argument is explained in detail on Microsoft's documentation page for robocopy, but I'll explain them here too.
The 1st argument specifies the path to the source folder. Please note that there are no trailing backslashes! If you include a backslash at the end, robocopy won't understand the input.
The 2nd argument specifies the path to the destination folder.
The 3rd argument can actually be multiple arguments. Here, the *.* specifies the file or files to be copied. Since wildcard characters (* or ?) are supported, *.* matches all files in the source directory (i.e., everything will be copied). *.* is the default parameter, so if you want all files to be copied, you don't even need to specify this parameter. If you want to copy, say, all files that end in .jpg, you'd write *.jpg. Or, if you want to copy, say, just two files file1.jpg and file2.mp4, you'd write those out explicitly, one after each other, as such robocopy "C:\Users\Person\Desktop\Original" "D:\Pictures\Copied" file1.jpg file2.mp4 /e /copy:DAT /dcopy:DAT /mt:16 /j /xjd /xa:s /r:1 /w:0 /log:"filename_path.txt".
The 4th argument /e copies subdirectories. This option automatically includes empty directories.
/copy:DAT specifies which file properties to copy. Here, D, A, and T means that the file's Data, Attributes, and Time Stamps properties will be copied. Refer to robocopy's documentation for more details.
/dcopy:DAT same as /copy:DAT except for folders.
/mt:16 creates multi-threaded copies with 16 threads. You can specify an integer between 1 and 128.
/j copies using unbuffered I/O (recommended for large files).
/xjd excludes junction points for directories.
/xa:s excludes "System" files.
/r:1 specifies the number of retries on failed copies. Here, it's set to 1. The default value is 1,000,000 (one million retries)!
/w:0 specifies the wait time between retries, in seconds. Here, it's set to 0, so 0 seconds are spent waiting.
/log:"filename_path.txt" writes the status output to the log file.
I have a scenario here, i am working on files clean up activity.
I have folders and withing the folder i have excel and pdf files. I want to retain the last two modified files and delete all other files.
Please help me writing the script.
Regards
NKS
To do something with all but the two most recently modified files can be done with a sort and then skipping two (broken over lines for ease of reading):
dir *.doc |
sort LastWriteTimeUtc -desc |
select -skip 2 |
# Do something like remove-item
(Using UTC to avoid problems when entering/leaving DST.)
I am trying to run following code through cmd.
"C:\Program Files\Beyond Compare 2\BC2.exe" #"C:\New Folder\Myscript.txt" "C:\New Folder\A.txt" "C:\New Folder\B.txt"
This will actually open Beyond Compare and compare two text files.
The problem is ,when i run this code on cmd[Version 6.1.7601] it runs correctly but when i run it on version 5.1.2600 , it shows a fatal error :- Could not find C:/New .
I understand the error is due to space in the name(New Folder) , but why is it running fine on Win 7 .Does two versions of cmd have some difference in the way they accept arguments ?
Content of Myscript.txt :-
file-report layout:side-by-side &
options:display-all &
output-to:%3 output-options:html-color,wrap-word %1 %2
I can't explain why it is not working, but I have some potential solutions
1) Run with the current directory at the location of the files
Since the space is in the folder name, and all files are in the same location, you can avoid the folder name by simply changing directory to that folder and using a relative path.
pushd "c:\new folder"
"C:\Program Files\Beyond Compare 2\BC2.exe" #Myscript.txt A.txt B.txt
Of course this will not work if your files are in different locations, or if the file names have spaces (assuming spaces are really the problem)
2) Use the short 8.3 names
I hate the short 8.3 names because of the many bugs associated with them. But sometimes they can be useful.
You can get the short name of a file or folder by using DIR /X. Or you could use the following in a batch script to programmatically get the short paths.
for %%A in ("C:\New Folder\Myscript.txt") do (
for %%B in ("C:\New Folder\A.txt") do (
for %%C in ("C:\New Folder\B.txt") do (
"C:\Program Files\Beyond Compare 2\BC2.exe" #"%%~fsA" "%%~fsB" "%%~fsC"
)
)
)
Of course the above will not do any good if short 8.3 names are disabled on your volume.
If i understood correctly Raymond's comment ,the parsing is done by Beyond Compare not cmd.
I tried to use
file-report layout:side-by-side &
options:display-all &
output-to:"%3" output-options:html-color,wrap-word "%1" "%2"
and it worked fine on XP but shows error on windows 7 .It seems the beyond compare behaves differently for different OS.