How to duplicate folder then rename folder and files inside it in Batch or Powershell to multiple folders [closed] - powershell

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Let's say I have this folder structure:
02548 //let's call this MASTER FOLDER, folder name are using site_id
|- 1. Master File
|- 02548_MSFI.pdf
|- 2. src
|- 02548_main.cpp
|- 3. Backup
|- alpha.svn
I also have site_id.txt file contains the name of side_id:
02548
03584
05482
07992
05861
What I want to do is to duplicate the MASTER FOLDER to new folders. So, the final result will be something like this:
|-02548 // MASTER FOLDER
| |- 1. Master File
| |- 02548_MSFI.pdf
| |- 2. src
| |- 02548_main.cpp
| |- 3. Backup
| |- alpha.svn
|-03584 //the folder name are taken from the list inside the site_id.txt
| |- 1. Master File
| |- 03584_MSFI.pdf //please notice the prefix of this file's name
| |- 2. src
| |- 03584_main.cpp //please notice the prefix of this file's name
| |- 3. Backup
| |- alpha.svn
|-05482 //the folder name are taken from the list inside the site_id.txt
| |- 1. Master File
| |- 05482_MSFI.pdf //please notice the prefix of this file's name
| |- 2. src
| |- 05482_main.cpp //please notice the prefix of this file's name
| |- 3. Backup
| |- alpha.svn
and so on until all the site_id from site_id.txt are here.
In the real world, site_id.txt will contains more than 1000 of list. So, doing this manually will be very painful.
How do I do this using batch script or powershell?

Don't know how you would do it, but this is how I would do it if I had a job and that task was assigned to me:
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q44093158.txt"
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
XCOPY /s /e "%sourcedir%\t w o\*" "%destdir%\%%a\" >nul
FOR /f "delims=" %%p IN ('dir /s /b "%destdir%\%%a\*#*"') DO (
SET "filename=%%~nxp"
CALL set "filename=%%filename:#=%%a%%"
CALL REN "%%p" "%%filename%%"
)
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
I used a file named q44093158.txt containing your data for my testing.
Within the source directory, (I actually tested with \t w o appended to ensure it worked with directorynames containing spaces), build the structure including the master files with the branch-number replaced by #
The code simply reads filename1 which contains the branch names one to a line, duplicates the directory structure at the destination, then looks for filenames containing #. With those files, it substitutes the branch name for the # and renames the file.
Done!

This PowerShell script and the file site_id.txt should be placed in the parent folder of 02548
## C:\Test\Copy-Template.ps1
$template = '02548'
foreach ($site in (Get-Content site_id.txt)) {
Get-ChildItem $template -recurse | Foreach-Object {
$NewName = $_.FullName -replace $template,$site
if ($_.PSIsContainer){
if (!(Test-path $NewName)){md $NewName|Out-Null}
} else {
copy $_.FullName $NewName -EA 0
}
}
}
Sample output:
> tree /F
C:.
│ Copy-Template.ps1
│ site_id.txt
│
└───02548
├───1. Master File
│ 02548_MSFI.pdf
│
├───2. src
│ 02548_main.cpp
│
└───3. Backup
alpha.svn
> .\Copy-Template.ps1
> tree /f
C:.
│ Copy-Template.ps1
│ site_id.txt
│
├───02548
│ ├───1. Master File
│ │ 02548_MSFI.pdf
│ │
│ ├───2. src
│ │ 02548_main.cpp
│ │
│ └───3. Backup
│ alpha.svn
│
├───03584
│ ├───1. Master File
│ │ 03584_MSFI.pdf
│ │
│ ├───2. src
│ │ 03584_main.cpp
│ │
│ └───3. Backup
│ alpha.svn
│
├───05482
...
├───05861
...
└───07992
├───1. Master File
│ 07992_MSFI.pdf
│
├───2. src
│ 07992_main.cpp
│
└───3. Backup
alpha.svn

#echo off
setlocal EnableDelayedExpansion
rem Call the subroutine, read data from site_id file
call :DuplicateTree < site_id.txt
goto :EOF
:DuplicateTree
rem Read MasterFolder from first line
set /P "masterFolder="
:nextFolder
rem Read and process next folders until EOF
set /P "nextFolder="
if errorlevel 1 exit /B
rem Duplicate folders first
md "%nextFolder%"
for /R "%masterFolder%" /D %%a in (*) do (
set "folder=%%a"
set "folder=!folder:*%cd%\=!"
md "!folder:%masterFolder%=%nextFolder%!"
)
rem Duplicate files
for /R "%masterFolder%" %%a in (*) do (
set "file=%%a"
set "file=!file:*%cd%\=!"
copy "%%a" "!file:%masterFolder%=%nextFolder%!"
)
goto nextFolder
Place this Batch file in the same folder that contain both site_id.txt file and 02548 Master Folder.

Related

Powershell navigating to unknown directory

I have stumbled the unfortunate situation, having to be in a directory in which another directory is located:
C:\Test\[Folder with unknown name]\theFileINeed.txt
The structure mentioned above originates from a Zip-file from an external source. So i can not change the structure.
My goal is to navigate to the Directory with the unknown name, so it is my working directroy and I can execute further commands there. (Like Get-Childitem e.g.)
Is there a simple way to e.g. use the cd command to move into that directory?
I have fiddled around a bit with Resolve-Path but couldn't find a helpful solution.
Thanks in advance.
Consider this structure:
C:\TMP\TEST
├───unknowndir1
│ │ nonuniquefile.txt
│ │ uniquefile.txt
│ │
│ ├───nonuniquesubdir
│ └───uniquesubdir
└───unknowndir2
│ nonuniquefile.txt
│
└───nonuniquesubdir
You could do cd .\test\*\uniquesubdir but you can't cd .\test\*\nonuniquesubdir as you'll gen an error (...) path (...) resolved to multiple containers. The same error is even with cd .\test\*\uniquesubdir\.. as if it didn't even check for existence of uniquesubdir.
So if you want to enter unknown directory based of a file it contains, you'd have to do something like this: cd (Get-Item .\test\*\uniquefile.txt).DirectoryName.
It will fail if you use nonuniquefile.txt as it again resolves to two different directories. You could enter the first of these directories with cd (Get-Item .\test\*\nonuniquefile.txt).DirectoryName[0] if you don't care which of them you use.

Match all files that are inside a folder and ignore one folder inside

I have the following directory structure:
root
├─ files
│ ├─ folder1
│ │ ├─ file1.js
│ | └─ file2.js
│ ├─ folder2
│ │ └─ file3.js
│ ├─ file4.js
| └─ file5.js
└─ config.js
How can I match every file inside of file (and subdirectories) except the files that are in folder1, in this case file3.js, file4.js and file5.js?
I know I could exclude folder1 with the following: files/!(folder1)/*.js, but this only matches file3.js.
Try **/files/{*.js,!(folder1)*/*.js}. You can test using globster.xyz
There is probably a more elegant way to do this as I am not too familiar with glob, but I think this will get what you are asking for.
import glob
exclude_pattern = ['folder1']
file_list = glob.glob('./files/**/*', recursive=True)
for pattern in exclude_pattern:
exclude_patternmatch = list(filter(lambda x: pattern in x, file_list))
for item in exclude_patternmatch:
file_list.remove(item)
print(file_list)
output:
['./files/file6.js', './files/file5.js', './files/folder2/file3.js', './files/folder2/file4.js']

Maintain SubSubFolder structure While Merging into Another Folder [Duplicate FolderNames Will Exist]

I currently receive emails for tickets and responses. They are automatically sent to folders as pdf. I create cover pages for them. So essential 3 sections that will eventually become one big pdf (cover, ticket, & response).
Ticket numbers are 14 digits and usually the emails contain that ticket number somewhere in the subject line (which is the pdf title). So I use BulkRenameUtility and Regex to rename every ticket to the 14 digit ticket number, with "-Ticket" after it. All responses then get named to the 14 digit ticket number, prefixed with a 2 (so that pdftk combines it last), and if there is multiple responses sequentially numbered. All covers are automatically generated with "10A-" then the 14 digit ticket number, then the job number. Ticket numbers are in the format YYMMDDHHNN####. So that makes pdftk compile these as Cover, ticket, then response.
But before pdftk can combine the pdfs into one. I need them to be in the same folder. I use a batch script to sort all covers into a folder with the 14 digit ticket name as the foldername, the same for the responses and tickets. So i end up with (depending on the number of tickets, right now I have 96) many subfolders like this.
.....OpenLocates
..........Current
...............Complete
....................[EMPTY]
...............Covers #There will be one cover per job.
....................18051400000001
.........................10A-18051400000001_218001.pdf
....................18051400000002
.........................10A-18051400000002_217022.pdf
...............Responses #There will be multiple responses per ticket.
....................18051400000001
.........................218051400000001.pdf
.........................218051400000001_1.pdf
.........................218051400000001_2.pdf
....................18051400000002
.........................218051400000002.pdf
.........................218051400000002_1.pdf
.........................218051400000002_2.pdf
...............Tickets #There *can* be multiple tickets per job.
....................18051400000001
.........................18051400000001-Ticket.pdf
....................18051400000002
.........................18051400000002-Ticket.pdf
What I need is for all those subfolders to merge into one. There should not ever be a duplicate filename since BRU does sequentially number duplicates when renaming the pdf files in the first place.
.....OpenLocates
..........Current
...............Complete
....................18051400000001
.........................10A-18051400000001_218001.pdf
.........................18051400000001-Ticket.pdf
.........................218051400000001.pdf
.........................218051400000001_1.pdf
.........................218051400000001_2.pdf
....................18051400000002
.........................10A-18051400000002_217022.pdf
.........................18051400000002-Ticket.pdf
.........................218051400000002.pdf
.........................218051400000002_1.pdf
.........................218051400000002_2.pdf
The batch script is this:
#echo on
::CALLALL
Call :SortCovers
Call :SortResponses
Call :SortTickets
goto :EOF
:SortCovers
cd L:\OpenLocates\Current\Covers
for /f %%a in ('dir /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :SortCoversFunction "%%~a"
)
goto :EOF
:SortCoversFunction
set file=%~1
set dir=%file:~4,14%
md "%dir%" 2>nul
move "%file%" "%dir%"
goto :EOF
:SortResponses
cd L:\OpenLocates\Current\Responses
for /f %%a in ('dir /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :SortResponsesFunction "%%~a"
)
goto :EOF
:SortResponsesFunction
set file=%~1
set dir=%file:~1,14%
md "%dir%" 2>nul
move "%file%" "%dir%"
goto :EOF
:SortTickets
cd L:\OpenLocates\Current\Tickets
for /f %%a in ('dir /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :SortTicketsFunction "%%~a"
)
goto :EOF
:SortTicketsFunction
set file=%~1
set dir=%file:~0,14%
md "%dir%" 2>nul
move "%file%" "%dir%"
goto :EOF
Right now i'm cut/pasting the folders and clicking OK on the merge popup in windows explorer.
But i have to teach my whole process to another person next week, and i'd like to simplify it down.
After I have all my folders merged I run a powershell script with PDFTK to combine the pdf files and save them in the parent folder.
I could really use some help on getting the subfolders of Covers, Responses and Tickets to move out to the Complete folder merging the duplicate foldernames to create one folder with all my files for each ticket number so I can run the following powershell script that does successfully combine them in the correct order.
$pdftk = "C:\SymLinks\Combine\pdftk.exe"
$inputFolder = "L:\OpenLocates\Current\Complete"
gci $inputfolder -r -include *.pdf | sort-object | group DirectoryName | % {& $PDFtk $_.group CAT OUTPUT "$($_.Name | Split-Path -Parent)\$($_.Name | Split-Path -Leaf).pdf" verbose}
Any help would be greatly appreciated. I've tried several different batch and powershell scripts and none seem to be working for me.
Edit: I do combine all the ticket numbers for one job into one folder before combining the PDFs. All the folders get renamed to the job name also before combining that final PDF.
I'd stay with the more modern script langugage.
I created a test environment on my ramdisk A:
## Q:\Test\2018\05\19\SO_50419164.ps1
$Sources = ("A:\OpenLocates\Current\Covers\",
"A:\OpenLocates\Current\Responses\",
"A:\OpenLocates\Current\Tickets\")
$Target = "A:\OpenLocates\Current\Complete\"
ForEach ($Source in $Sources){
Get-ChildItem $Source -Directory | ForEach-Object {
$TargetSub = Join-Path $Target $_.Name
If (!(Test-Path $TargetSub)){ MD $TargetSub |Out-Null}
Get-ChildItem $_.FullName -File | Move -Dest $TargetSub
Remove-Item $_.FullName
}
}
Tree a: /F before
A:\
└───OpenLocates
└───Current
├───Complete
├───Covers
│ ├───18051400000001
│ │ 10A-18051400000001_218001.pdf
│ │
│ └───18051400000002
│ 10A-18051400000002_217022.pdf
│
├───Responses
│ ├───18051400000001
│ │ 218051400000001.pdf
│ │ 218051400000001_1.pdf
│ │ 218051400000001_2.pdf
│ │
│ └───18051400000002
│ 218051400000002.pdf
│ 218051400000002_1.pdf
│ 218051400000002_2.pdf
│
└───Tickets
├───18051400000001
│ 18051400000001-Ticket.pdf
│
└───18051400000002
18051400000002-Ticket.pdf
And after running the script:
A:\
└───OpenLocates
└───Current
├───Complete
│ ├───18051400000001
│ │ 10A-18051400000001_218001.pdf
│ │ 18051400000001-Ticket.pdf
│ │ 218051400000001.pdf
│ │ 218051400000001_1.pdf
│ │ 218051400000001_2.pdf
│ │
│ └───18051400000002
│ 10A-18051400000002_217022.pdf
│ 18051400000002-Ticket.pdf
│ 218051400000002.pdf
│ 218051400000002_1.pdf
│ 218051400000002_2.pdf
│
├───Covers
├───Responses
└───Tickets

Prevent stemming of words starting with # in PostgreSQL full text search

Basically, I want to be able to get an exact match (hashtag included) for queries like this:
=#SELECT to_tsvector('english', '#adoption');
to_tsvector
-------------
'adopt':1
Instead, I want for words starting with #, to see:
=#SELECT to_tsvector('english', '#adoption');
to_tsvector
-------------
'#adoption':1
Is this possible with psql full text search?
Before you search or index, you could replace each # character with some other character that you don't use in your texts, but which changes the parser's interpretation:
test=> SELECT alias, lexemes FROM ts_debug('english', '#adoption');
┌───────────┬─────────┐
│ alias │ lexemes │
├───────────┼─────────┤
│ blank │ │
│ asciiword │ {adopt} │
└───────────┴─────────┘
(2 rows)
test=> SELECT alias, lexemes FROM ts_debug('english', '/adoption');
┌───────┬─────────────┐
│ alias │ lexemes │
├───────┼─────────────┤
│ file │ {/adoption} │
└───────┴─────────────┘
(1 row)

Using box-drawing Unicode characters in batch files

I am making a batch file that uses these characters:
˧ ˥ ˪ ˫
It is not working, it just terminates itself.
I have seen people use characters like this:
Å
It isnt the character but it turns into a character, can someone give me a list of these, shows the type of letter above and what it turns into?
If you want to write console batch files that use those characters, you need an editor that will save the batch file using the console's code page. To check what that is, type:
C:\>chcp
Active code page: 437
This is the result for my US Windows system. Western European versions of Windows will often be code page 850.
A good editor is Notepad++. Set that encoding in the editor (Encoding, Character sets, Western European, OEM-US) and copy the following characters into it:
#echo off
echo ╔═╦═╗ ┌─┬─┐ ╓─╥─╖ ╒═╤═╕
echo ║ ║ ║ │ │ │ ║ ║ ║ │ │ │
echo ╠═╬═╣ ├─┼─┤ ╟─╫─╢ ╞═╪═╡
echo ║ ║ ║ │ │ │ ║ ║ ║ │ │ │
echo ╚═╩═╝ └─┴─┘ ╙─╨─╜ ╘═╧═╛
Save the file as test.bat and run it from the console:
C:\>test
╔═╦═╗ ┌─┬─┐ ╓─╥─╖ ╒═╤═╕
║ ║ ║ │ │ │ ║ ║ ║ │ │ │
╠═╬═╣ ├─┼─┤ ╟─╫─╢ ╞═╪═╡
║ ║ ║ │ │ │ ║ ║ ║ │ │ │
╚═╩═╝ └─┴─┘ ╙─╨─╜ ╘═╧═╛
When you open the file again in Notepad++, it is possible that you will see something like:
#echo off
echo ÉÍËÍ» ÚÄÂÄ¿ ÖÄÒÄ· ÕÍÑ͸
echo º º º ³ ³ ³ º º º ³ ³ ³
echo ÌÍÎ͹ ÃÄÅÄ´ ÇÄ×Ķ ÆÍØ͵
echo º º º ³ ³ ³ º º º ³ ³ ³
echo ÈÍÊͼ ÀÄÁÄÙ ÓÄÐĽ ÔÍÏ;
Since there is no indication in the file what code page the characters in it represent, Notepad++ may choose the so-called ANSI code page. On US Windows that is Windows-1252. Just select the OEM-US encoding again to display it properly.
The characters you can use depend on the console codepage that is set. You can see it with chcp. On many systems it's 850 or 437. You can then look up the characters in that code page or find one that supports the characters you need and use chcp in your batch file to set it early on.
Note though that this is a setting for the process, so if someone needs to continue working with the console window afterwards it might not be nice to change their drapes to another colour. Also code page 65001 is UTF-8, but has a set of problems and drawbacks that make it rather tricky to use.
Note also that Notepad is not a useful text editor for writing batch files that need more than ASCII, because the legacy encoding in the non-console part of Windows is a different one. This might be what you mean that Å turns into another character.
You just need this equivalences file that works in any text editor, including the standard Windows Notepad:
Notepad: ┌┬┐ ├┼┤ └┴┘ ─ │
cmd.exe: Ú¿ ÃÅ´ ÀÁÙ Ä ³
Notepad: ╔╦╗ ╠╬╣ ╚╩╝ ═ ║
cmd.exe: ÉË» Ìι Èʼ Í º
Copy this table into a text file, that you must save as Unicode encoding. Then, when you want to insert a character in your Batch file, just choose the one below the graphic char you want to show.
Note: These characters are correct for code pages 850 or 437.
This table was copied from this answer.