mark reduxmotion
asked on
batch file or some other automation script for simple-ish file operation
Hello,
I shoot RAW video, result is that each take is a separate directory filled with photos camera takes 24 photos per second(dependent on FPS setting), each one of the photos is named sequentialy in the filename.
so each take is a subdirectory in the root directory
I'm trying to create a script that would traverse the root directory and all it's subdirectories and simply copy files(photo/image) based on their filename, and just copy every 1440th file out of each subdirectory, effectively giving me stills from the video footage every 1 minute, to a designated directory.
Does that make sense? I'm just looking to have a batch file to perform that, this would give me a sampling of all the footage from the day in 1 minute increments, batch file or if there is another way to automate this copying setup with some amount of control as to the interval, that would be great.
here are example three sequential file names from one of the directories.
bmpcc 001_1_2015-09-17_0400_C000 5_000000.d ng
bmpcc 001_1_2015-09-17_0400_C000 5_000001.d ng
bmpcc 001_1_2015-09-17_0400_C000 5_000002.d ng
and so on, so the number of files in each directory varies, script would need to stop when the last file is considered and go to the next directory to copy files from there
could someone help me with a script or write it for me if it's simple or point me to an application that could be setup to do something like this?
I shoot RAW video, result is that each take is a separate directory filled with photos camera takes 24 photos per second(dependent on FPS setting), each one of the photos is named sequentialy in the filename.
so each take is a subdirectory in the root directory
I'm trying to create a script that would traverse the root directory and all it's subdirectories and simply copy files(photo/image) based on their filename, and just copy every 1440th file out of each subdirectory, effectively giving me stills from the video footage every 1 minute, to a designated directory.
Does that make sense? I'm just looking to have a batch file to perform that, this would give me a sampling of all the footage from the day in 1 minute increments, batch file or if there is another way to automate this copying setup with some amount of control as to the interval, that would be great.
here are example three sequential file names from one of the directories.
bmpcc 001_1_2015-09-17_0400_C000
bmpcc 001_1_2015-09-17_0400_C000
bmpcc 001_1_2015-09-17_0400_C000
and so on, so the number of files in each directory varies, script would need to stop when the last file is considered and go to the next directory to copy files from there
could someone help me with a script or write it for me if it's simple or point me to an application that could be setup to do something like this?
ASKER
I think you misunderstood, I meant every 1440th file in directory, so for example, based on example filenames I posted...
bmpcc 001_1_2015-09-17_0400_C000 5_000000.d ng
bmpcc 001_1_2015-09-17_0400_C000 5_001440.d ng
bmpcc 001_1_2015-09-17_0400_C000 5_002880.d ng
bmpcc 001_1_2015-09-17_0400_C000 5_003960.d ng
and so on, as long as the file exists, I would also like to be able to easily change the increment from 1440 to something else, for example 6000
each directory will have vastly different number of files so before copying script needs to check if file with that name exists and if it doesn't skip to next directory and stop over, from 1440 for example...
bmpcc 001_1_2015-09-17_0400_C000
bmpcc 001_1_2015-09-17_0400_C000
bmpcc 001_1_2015-09-17_0400_C000
bmpcc 001_1_2015-09-17_0400_C000
and so on, as long as the file exists, I would also like to be able to easily change the increment from 1440 to something else, for example 6000
each directory will have vastly different number of files so before copying script needs to check if file with that name exists and if it doesn't skip to next directory and stop over, from 1440 for example...
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
again, only a single file will match these answers, I'm looking for a batch file or whatever that may be that will copy files with multiples of the number 1440 in the name, or whatever other number I may set, plus it would need to traverse all subdirectories under specified root directory and in each directory do the same, copy all existing files with multiplied number 1440 in their name
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Here's a batch that copies every nth file (not necessarily multiplies, if the numbers aren't contiguous). It's currently in test mode and will only display the files it would copy; remove the REM in line 13 to run it for real.
@echo off
setlocal enabledelayedexpansion
set Source=C:\Temp\Takes
set Target=C:\Temp\Target
set Increment=1440
set Mask=*.dng
for /f "delims=" %%a in ('dir /b /a:d /o:n "%Source%\*.*"') do (
echo Processing %%a ...
set /a Index = %Increment%
for /f "delims=" %%b in ('dir /b /a:-d /o:n "%Source%\%%a\%Mask%"') do (
if !Index!==%Increment% (
echo - '%%b'
REM copy "%Source%\%%a\%%b" "%Target%"
set /a Index = 1
) else (
set /a Index += 1
)
)
)
ASKER
I tried the powershell script and here is what happens
PS C:\Users\user> gci "I:\Rob day 1\bmpcc 001_1_2015-09-17_0341_C000 1" -File -Recurse | ?([int]$_.Name.Substring($ _.Na
me.Length - 6, 6) % 1440 -eq 0) | Copy-Item $_.FullLength "I:\stills\"+$_.Name
You cannot call a method on a null-valued expression.
At line:1 char:1
+ gci "I:\Rob day 1\bmpcc 001_1_2015-09-17_0341_C000 1" -File -Recurse ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
PS C:\Users\user> gci "I:\Rob day 1\bmpcc 001_1_2015-09-17_0341_C000
me.Length - 6, 6) % 1440 -eq 0) | Copy-Item $_.FullLength "I:\stills\"+$_.Name
You cannot call a method on a null-valued expression.
At line:1 char:1
+ gci "I:\Rob day 1\bmpcc 001_1_2015-09-17_0341_C000
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
$Source = "C:\temp\Takes\*.dng"
$Target = "C:\temp\Target"
$Increment = 1440
Get-ChildItem -Path $Source -File -Recurse |
Where-Object {
($_.BaseName.Split("_")[-1 ] % $Increment) -eq 0
} |
ForEach-Object {
Copy-Item -Path $_.FullName -Destination $Target -WhatIf
}
will this one also traverse all subdirectiories under takes? so for example C:\temp\Takes\1\, C:\temp\Takes\2\, C:\temp\Takes\3\ and so on?
$Target = "C:\temp\Target"
$Increment = 1440
Get-ChildItem -Path $Source -File -Recurse |
Where-Object {
($_.BaseName.Split("_")[-1
} |
ForEach-Object {
Copy-Item -Path $_.FullName -Destination $Target -WhatIf
}
will this one also traverse all subdirectiories under takes? so for example C:\temp\Takes\1\, C:\temp\Takes\2\, C:\temp\Takes\3\ and so on?
Yes, that's what the "-Recurse" does (or -R in the condensed version).
You can just run it as it is, it will only generate console output for the files it would copy as long as Copy-Item has the -WhatIf argument.
Or replace the "Copy-Item ..." line with Write-Host $_.FullName, which makes the output more readable than the -WhatIf.
You can just run it as it is, it will only generate console output for the files it would copy as long as Copy-Item has the -WhatIf argument.
Or replace the "Copy-Item ..." line with Write-Host $_.FullName, which makes the output more readable than the -WhatIf.
ASKER
now you got me confused, sorry, could you post the full script with the modifications you mentioned? I've never used the PS script in my life...
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I don't think it works, what am I doing wrong?
PS C:\Users\user> $Source = "I:\rob day 22\*.dng" |$Target = "I:\stills\" | $Increment = 1440 | Get-ChildItem -Path
$Source -File -Recurse | Where-Object { | ($_.BaseName.Split("_")[-1 ] % $Increment) -eq 0 | } | ForEach-Object { | C
opy-Item -Path $_.FullName -Destination $Target -WhatIf}
At line:1 char:34
+ $Source = "I:\rob day 22\*.dng" |$Target = "I:\stills\" | $Increment ...
+ ~~~~~~~
Expressions are only allowed as the first element of a pipeline.
At line:1 char:59
+ ... = "I:\rob day 22\*.dng" |$Target = "I:\stills\" | $Increment = 1440 ...
+ ~~~~~~~~~~
Expressions are only allowed as the first element of a pipeline.
At line:1 char:139
+ ... Get-ChildItem -Path $Source -File -Recurse | Where-Object { | ($_.Bas ...
+ ~
An empty pipe element is not allowed.
At line:1 char:190
+ ... -Object { | ($_.BaseName.Split("_")[-1 ] % $Increment) -eq 0 | } | For ...
+ ~
An empty pipe element is not allowed.
At line:1 char:212
+ ... e.Split("_")[-1] % $Increment) -eq 0 | } | ForEach-Object { | Copy-It ...
+ ~
An empty pipe element is not allowed.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordE xception
+ FullyQualifiedErrorId : ExpressionsMustBeFirstInPi peline
PS C:\Users\user>
PS C:\Users\user> $Source = "I:\rob day 22\*.dng" |$Target = "I:\stills\" | $Increment = 1440 | Get-ChildItem -Path
$Source -File -Recurse | Where-Object { | ($_.BaseName.Split("_")[-1
opy-Item -Path $_.FullName -Destination $Target -WhatIf}
At line:1 char:34
+ $Source = "I:\rob day 22\*.dng" |$Target = "I:\stills\" | $Increment ...
+ ~~~~~~~
Expressions are only allowed as the first element of a pipeline.
At line:1 char:59
+ ... = "I:\rob day 22\*.dng" |$Target = "I:\stills\" | $Increment = 1440 ...
+ ~~~~~~~~~~
Expressions are only allowed as the first element of a pipeline.
At line:1 char:139
+ ... Get-ChildItem -Path $Source -File -Recurse | Where-Object { | ($_.Bas ...
+ ~
An empty pipe element is not allowed.
At line:1 char:190
+ ... -Object { | ($_.BaseName.Split("_")[-1
+ ~
An empty pipe element is not allowed.
At line:1 char:212
+ ... e.Split("_")[-1] % $Increment) -eq 0 | } | ForEach-Object { | Copy-It ...
+ ~
An empty pipe element is not allowed.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordE
+ FullyQualifiedErrorId : ExpressionsMustBeFirstInPi
PS C:\Users\user>
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Two possibilities:
1. Click "Select all" under the code box, copy it into the clipboard, paste it into an open PS console, hit Enter; this will only display the files it would copy:
In a PS console, enter
C:\Temp\whatever.ps1
If you get an error message about unsigned scripts and the execution policy, enter
Set-ExecutionPolicy RemoteSigned -Force
and try again.
1. Click "Select all" under the code box, copy it into the clipboard, paste it into an open PS console, hit Enter; this will only display the files it would copy:
gci "I:\rob day 22\*.dng" -File -R | ? {!($_.BaseName.Split("_")[-1] % 1440)} | % {Write-Host $_.FullName}
2. Click "Select all" under the "fleshed out" script, copy and paste it into Notepad, change $Source, $Target, $Increment to your likings, save it for example as C:\Temp\whatever.ps1.In a PS console, enter
C:\Temp\whatever.ps1
If you get an error message about unsigned scripts and the execution policy, enter
Set-ExecutionPolicy RemoteSigned -Force
and try again.
ASKER
but I don't see the destination folder here for matching files?
gci "I:\rob day 22\*.dng" -File -R | ? {!($_.BaseName.Split("_")[ -1] % 1440)} | % {Write-Host $_.FullName}
Sorry to be a pain, it's been years since I did any code writing, I'm now a DP... it's healthier then programming, but this code looks like magic to me now =)
gci "I:\rob day 22\*.dng" -File -R | ? {!($_.BaseName.Split("_")[
Sorry to be a pain, it's been years since I did any code writing, I'm now a DP... it's healthier then programming, but this code looks like magic to me now =)
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Target folders are created based on source file folder.
Make a .bat of this. Change the value after the = for RootDir, CopyToDir, Sequence to your needs:
Open in new window