Copy all files from a folder to another one - copy

I want to copy all files from a folder to another one in Stata.
I have used the following code:
local dlist: dir "$dir" dirs "*"
foreach d of local dlist {
local file: dir "$dir\"`d'"" files "*.dta"
foreach f of local file{
copy `f' "$dir/PROGRAMMATION/INITIALES"
}
}
However, Stata returns:
invalid syntax
$dir is the actual directory where this do-file is located.

The following works for me:
global dir /Users/monkey/Downloads
local dlist: dir "$dir" dir "*"
foreach d of local dlist {
local file: dir "$dir/`d'" files "*.dta"
foreach f of local file {
copy "$dir/`d'/`f'" "/Users/monkey/testdir/`f'"
}
}
Note that the code will copy all Stata dataset files contained in every sub-directory of /Users/monkey/Downloads to the directory /Users/monkey/testdir/.
If you just want to copy all Stata dataset files from /Users/monkey/Downloads to /Users/monkey/testdir/ one loop will suffice:
global dir /Users/monkey/Downloads
local file: dir "$dir" files "*.dta"
foreach f of local file{
copy "$dir`f'" "/Users/monkey/testdir/`f'"
}

Related

robocopy to update contents of folder from local to production

I want to copy some folders from my local to production. The thing is I want to update the production only when the folder structure exists. I cannot use copy paste as well since the name of the files are different, when I do copy paste I end up with 4 files: file 1, file2, file a, file b.
Local:
Directory1: file1, file2
Directory2: abc.txt, hqyh.txt
Production:
Directory1: xyz.txt, jht.txt
Directory2: abc.txt, cde.txt
Directory3: p.txt, q.txt
Directory4: t.txt, u.txt
My result:
Production:
Directory1: file1, file2
Directory2: abc.txt, hqyh.txt
Desired result:
Production:
Directory1: file1, file2
Directory2: abc.txt, hqyh.txt
Directory3: p.txt, q.txt
Directory4: t.txt, u.txt
Code:
robocopy.exe C:\Local E:\Production /MIR
robocopy can't do what you're asking (skip folders that don't exist in the source) when you run it on the parent folder(s). Run it on the child folders instead.
$src = 'C:\Local'
$dst = 'E:\Production'
Get-ChildItem $src | ForEach-Object {
robocopy $_.FullName (Join-Path $dst $_.Name) /mir
}

Code for automating incremented ZIP compression?

I'm trying to ZIP a folder of 800 pictures, with each ZIP file containing only 10 or less pictures, so I should end up with 80 ZIP files. If anyone knows the BAT file code to do this, I would be very appreciative. I also do NOT want to delete the files after they've been zipped.
I know that I'll probably be using 7-Zip, but I just can't seem to find an answer for this anywhere. Thanks!
Try the following PowerShell:
# Setup variables (Change)
$ZipFolder = "T:\YourFolder\WithFiles\ToZip"
$7Zip = "C:\Program Files\7-Zip\7z.exe"
$NewZipsFolder = "T:\FolderToPut\AllOfThe\ZipsIn"
# Script Variables
$pendingFiles = #()
$fileNumber = 1
# Get a list of all the files to be zipped
Get-ChildItem $ZipFolder | sort $_.FullName | ForEach-Object { $pendingFiles += $_.FullName }
# While there are files still to zip
While($pendingFiles){
# Select first 10 files to zip and zip them
$ToZip = $pendingFiles | Select -First 10
& $7Zip "a" "$NewZipsFolder\File-$fileNumber.7z" $ToZip
# Remove first 10 zipped files from pending files array
$pendingFiles = $pendingFiles | Where-Object { $ToZip -notcontains $_ }
$fileNumber++
}
This will create a list of all the file that need to be zipped. Then zip them up in batches of 10 files using 7z.exe (7-zip).
Note: For the variables $ZipFolder & $NewZipsFolder do not put a trailing backslash on the folder paths (\).
You could store an list of files in Powershell using something along the lines of
$fileList = Get-Item -Path "C:\MyPhotosDir\*"
Then set an alias for 7zip
set-alias sz "$env:ProgramFiles\7-Zip\7z.exe"
Then create a loop with a counter along the lines of
$i = 1
foreach $file in $fileList
#Build foder name name
$folderDir = "C:\MyPhotoArchive$($i - ($i % 10) + 1).7z"
sz a -t7z $folderDir $file.filename
end for
I have been writing in VB for a short while and so apologies if the Powershell syntax is a bit off. Essentially that should add 10 files to "C:\MyPhotoArchive1", 10 files to "C:\MyPhotoArchive2". I haven't added files to an archive using 7zip for a long time but I think the call just uses a a and should add files to an archive, creating one when needed.

Moving files based on file name with powershell

I need to parse a file name and move the file to a folder based on part of the file name.
Lets say I have several files in a folder C:\SYSLOG\Servers and Firewall\Logs. They are log files from several different servers or devices.. I need to move them to our NAS for archival. Sample file names:
Boston.North.Application.S01.120613.log
Boston.South.Application.S12.122513.log
Lexington.System.S02.073013.log
Lexington.System.S22.073013.log
Madison.IPS.S01.050414.txt
I need to move them to a corresponding folder on the NAS. My folder structure looks like this:
\\NAS\Logs\Boston North Application
\\NAS\Logs\Boston South Application
\\NAS\Logs\Lexington System
\\NAS\Logs\Madison IPS
So basically I am wanting to parse the file name for everything to the left of the server (Sxx), and replace the . with spaces to create the destination folder name.
The files are not always .log files. All files have a .Sxx in the name and xx will always be numbers. If destination folder does not exist, then skip the file. There are no subfolders in C:\SYSLOG\Servers and Firewall\Logs.
I think I am trying to do something similar to powershell to move files based on part of file name
Rely on the fact that everything in the file name up until the Sxx block is the destination if you just replace the . with a space:
# Retrieve the filenames
$Directory = "C:\SYSLOG\Server and Firewall\Logs"
$FileNames = (Get-Item $Directory).GetFiles()
foreach($FileName in $FileNames)
{
# Split the filename on "."
$Pieces = $FileName-split"\."
# Counting backwords, grab the pieces up until the Sxx part
$Start = $Pieces.Count*-1
$Folder = $Pieces[$Start..-4]-join" "
# Build the destination path
$Destination = "\\NAS\Logs\{0}\" -f $Folder
# Test if the destination folder exists and move it
if(Test-Path $Destination -PathType Container)
{
Move-Item -Path $FileName -Destination $Destination
}
}
Final Version.
# Retrive list of files
# $sDir = Source Directory
$sDir = "C:\Temp\Logs\"
# Generate a list of all files in source directory
$Files = (Get-ChildItem $sDir)
# $tDir = Root Target Directory
$tDir = "C:\Temp\Logs2\"
# Loop through our list of file names
foreach($File in $Files)
{
# $wFile will be our working file name
$wFile = $File.Name
# Find .Sx in the file name, where x is a number
if ($wFile -match ".S0")
{
# tFile = Trimmed File Name
# We now remove everything to the right of the . in the .Sx of the file name including the .
$tFile = $wFile.substring(0,$wFile.IndexOf('.S0'))
}
# If we do not find .S0 in string, we search for .S1
elseif ($wFile -match ".S1")
{
$tFile = $wFile.substring(0,$wFile.IndexOf('.S1'))
}
# If we do not find .S0, or S1 in string, then we search for .S2
elseif ($wFile -match ".S2")
{
$tFile = $wFile.substring(0,$wFile.IndexOf('.S2'))
}
# Now we exit our If tests and do some work
# $nfold = The name of the sub-folder that the files will go into
# We will replace the . in the file name with spaces
$nFold = $tFile.replace("."," ")
# dFold = the destination folder in the format of \\drive\folder\SubFolder\
$dFold = "$tDir$nFold"
# Test if the destination folder exists
if(Test-Path $dFold -PathType Container)
{
# If the folder exists then we move the file
Move-Item -Path $sDir$File -Destination $dFold
# Now we just write put what went where
Write-Host $File "Was Moved to:" $dFold
Write-Host
}
# If the folder does not exist then we leave it alone!
else
{
# We write our selves a note that it was not moved
Write-Host $File "Was not moved!"
}
# Now we have a drink!
}

Creating a folder on a basis of filename and move the file to that folder

I have a folder with MANY files like this
Character 1 - object one.txt
Character 4 - Object two.txt
and so on.
I would like to create subfolders based on the part before " -" and move the files into that folder.
I haven't touched PS for quite a while and I am sorry to say that I am unsure where to start except for GCI..
Any help would be greatly appreciated!
#Change Current Directory to the Folder with txt files
cd C:\path\to\folder
#List all the file contents and pipe to a foreach loop
Get-ChildItem -file | % {
#Split the file name at the dash, take the first half, and trim the spaces
#($_ is the pipeline variable so in this case it represents each file)
$folder = ($_ -split "-")[0].trim()
#if the folder doesn't exist, create it
if(-not (Test-path $folder)) {
New-item $folder -ItemType Directory
}
#Move file to the folder
Move-item $_ $folder
}

How to zip only files and not the full path hierarchy with DotNetZip in powershell?

I'm trying to zip up log using DotNetZip and powershell. The files are in C:\user\temp\logs When I loop through the logs in the directory and add them to the zip file, I end up with the folder hierarchy and the log files when I only want the log files.
So the zip ends up containing:
-user
└temp
└logs
└log1.log
log2.log
log3.log
When I want the zip file to contain is:
log1.log
log2.log
log3.log
Here is the script I'm running to test with:
[System.Reflection.Assembly]::LoadFrom("c:\\\User\\bin\\Ionic.Zip.dll");
$zipfile = new-object Ionic.Zip.ZipFile("C:\user\temp\logs\TestZIP.zip");
$directory = "C:\user\temp\logs\"
$children = get-childitem -path $directory
foreach ($o in $children)
{
if($o.Name.EndsWith(".log")){
$e = $zipfile.AddFile($o.FullName)
}
}
$zipfile.Save()
$zipfile.Dispose()
There is an AddFile where you can override the filename in the archive:
public ZipEntry AddFile(
string fileName,
string directoryPathInArchive
)
fileName (String)
The name of the file to add. The name of the file may be a relative
path or a fully-qualified path.
directoryPathInArchive (String)
Specifies a directory path to use to override any path in the fileName.
This path may, or may not, correspond
to a real directory in the current
filesystem. If the files within the
zip are later extracted, this is the
path used for the extracted file.
Passing null (Nothing in VB) will use
the path on the fileName, if any.
Passing the empty string ("") will
insert the item at the root path
within the archive.
Try this:
$e = $zipfile.AddFile($o.FullName, $o.Name)
It is also possible that this does what you want:
$e = $zipfile.AddFile($o.FullName, "")
Not tested, but I think this should work.
[System.Reflection.Assembly]::LoadFrom("c:\\\User\\bin\\Ionic.Zip.dll");
$zipfile = new-object Ionic.Zip.ZipFile("C:\user\temp\logs\TestZIP.zip");
$directory = "C:\user\temp\logs\"
set-location $directory
$children = get-childitem *.log
foreach ($o in $children)
{
$e = $zipfile.AddFile($o.Name)
}
}
$zipfile.Save()
$zipfile.Dispose()