I am not sure if it's possible. i want to add filename at the end of text file each line.
assume i have a text file Sam_NEW.txt Tom_New.txt Robin_New.txt etc. inside the text follow line available
test1.rar
test2.rar
test3.rar
i want to have output
copy "C:\test1.rar" "F:\Sam_NEW\"
copy "C:\test2.rar" "F:\Sam_NEW\"
copy "C:\test3.rar" "F:\Sam_NEW\"
copy "C:\test1.rar" "F:\Tom_New\"
copy "C:\test2.rar" "F:\Tom_New\"
copy "C:\test3.rar" "F:\Tom_New\"
copy "C:\test1.rar" "F:\Robin_New\"
copy "C:\test2.rar" "F:\Robin_New\"
copy "C:\test3.rar" "F:\Robin_New\"
and save the text files. english is not my first language here is the image what i am trying to do
https://i.imgur.com/V2VTHa4.png
here is replace code so far i have.
(Get-Content C:\temp\*.txt) -creplace '^', '"C:\' | Set-Content C:\temp\*.txt
(Get-Content C:\temp\*.txt) -creplace '$', '"F:\HOW TO add here filename \"' | Set-Content C:\temp\*.txt
i am stuck in last part. how to add file name for the destination folder?
You'll want something like this:
$item = get-item -path "C:\temp\test.txt"
$lines = get-content -path $item.fullname
$newfileoutput = #()
foreach ($line in $lines){
$newfileoutput += 'copy "C:\' + $line + '" "F:\' + $item.basename + '\"'
}
$newfileoutput | set-content $item.fullname
But I can only encourage you to deepen your knowledge of simple cmdlets like get-item, get-content and the like. I don't have the impression that you understand the code you're writing. Sometimes, less code (and more pipelining) is making things more complicated. Try and write code that you understand.
I don't know that this code will do exactly what you're looking for, but I've tried to write it in a clear way with lots of explanation. Hopefully the techniques and cmdlets in here are helpful to you.
$RarFileNames = Get-ChildItem -Path C:\Temp -Filter *.rar | Select-Object -ExpandProperty Name
$NewFolderPaths = Get-ChildItem -Path F:\ -Directory | Select-Object -ExpandProperty FullName
foreach( $NewFolderPath in $NewFolderPaths )
{
foreach( $RarFile in $RarFileNames )
{
# EXAMPLE: C:\Temp\test1.rar
$RarFilePath = Join-Path -Path $RarFolderPath -ChildPath $RarFile
# EXAMPLE: Sam_New.txt
$NewFileName = (Split-Path $NewFolderPath -Leaf) + '.txt'
# EXAMPLE: F:\Sam_NEW\Sam_NEW.txt
$NewFilePath = Join-Path -Path $NewFolderPath -ChildPath ($NewFileName)
# This is the string that will be saved in the .txt file
# EXAMPLE: copy "C:\Temp\test1.rar" "C:\Sam_NEW\"
$StringToOutput = 'copy "' + $RarFilePath + '" "' + $NewFolderPath + '"'
# Append that string to the file:
Add-Content -Value $StringToOutput -Path $NewFilePath
}
}
Related
This PowerShell script is intended to copy photos from one or more source directories to a destination directory, organizing them by image type (JPEG, PNG, BMP, and HEIC).
It asks the user to enter the paths of the source directories and the source directories to exclude, as well as the path of the destination directory. These paths are stored in the variables $sources, $excluded, and $destination, respectively.
The script then converts the string contained in $sources into an array using the -split instruction, which allows for splitting a string based on a specified separator (here, a comma). If the user did not specify any source directories to exclude, the $excluded variable is initialized to an empty array using the Where-Object instruction.
The path of the destination directory is added to the $excluded array in order to avoid copying the photos to the destination directory itself.
The script then checks if the destination directory exists, and creates it if it does not using the New-Item instruction. It also creates destination directories for each file type (JPEG, PNG, BMP, and HEIC).
Finally, the script searches the computer's file system for files and copies the found photos to the destination directories according to their extension. It uses the Get-ChildItem instruction to retrieve the files in the source directories and the Copy-Item command to copy these files to the destination directories. The Where-Object clause is used to verify that the file is not in one of the excluded source directories.
$sources = Read-Host "Please enter the paths of the source directories (separated by commas) :"
$excluded = Read-Host "Please enter the paths of the source directories to exclude (separated by commas) :"
$destination = Read-Host "Please enter the path of the destination directory :"
$sources = $sources -split ","
$excluded = $excluded -split "," | Where-Object {$_}
$excluded += $destination
if (!(Test-Path $destination)) { New-Item -ItemType Directory -Path $destination }
"JPG", "PNG", "BMP", "HEIC" | ForEach-Object { New-Item -ItemType Directory -Path "$destination\$_" }
foreach ($source in $sources) {
if ($excluded -notcontains $source) {
"jpg", "png", "bmp", "heic" | ForEach-Object {
$extension = $_.ToUpper()
Get-ChildItem -Recurse $source -Filter "*.$_" | Where-Object {$_.Directory.FullName -notcontains $excluded} | Copy-Item -Destination "$destination\$extension"
}
}
}
This script works very well except that it still adds the photos of the excluded folders! Why ?
Replace:
$_.Directory.FullName -notcontains $excluded
with the following, which reverses the operands passed to the -notcontains operator:
$excluded -notcontains $_.Directory.FullName
Alternatively, use the related -notin operator:
$_.Directory.FullName -notin $excluded
Both -contains / -notcontains and -in / -notin test an array (collection) for containing a scalar (single object), through element-by-element equality testing. They only differ by the order of operands:
# -contains / -notcontains: array is the *LHS* (left-hand side) operand
#(1, 2, 3) -contains 2 # -> $true
# -in / -notin: array is the *RHS* (right-hand side)
2 -in #(1, 2, 3) # -> $true
I would use a regex for this to exclude the folders.
Also I'd use Group-Object to group the found files by extension, making it easier to copy to the destination folders:
$sources = Read-Host "Please enter the paths of the source directories (separated by commas) :"
$excluded = Read-Host "Please enter the paths of the source directories to exclude (separated by commas) :"
$destination = Read-Host "Please enter the path of the destination directory :"
$sources = #($sources -split "," | Where-Object {$_ -match '\S'}).Trim()
$excluded = #($excluded -split "," | Where-Object {$_ -match '\S'}).Trim() + $destination
# create a regex of the folders to exclude
# each folder will be Regex Escaped and joined together with the OR symbol '|'
$notThese = ($excluded | ForEach-Object { [Regex]::Escape($_) }) -join '|'
# enumerate the paths for the specified files
Get-ChildItem -Path $sources -Recurse -File -Include "*.JPG", "*.PNG", "*.BMP", "*.HEIC" |
Where-Object{ $_.DirectoryName -notmatch $notThese } |
Group-Object Extension |
ForEach-Object {
$targetPath = Join-Path -Path $Destination -ChildPath $_.Name.TrimStart(".").ToUpper()
# create the target path if this does not already exist
$null = New-Item -Path $targetPath -ItemType Directory -Force
# next copy the files in this group
$_.Group | Copy-Item -Destination $targetPath -Force
}
I have the following problem and I would really appreciate it if I could get some help on that front. I am getting a constant flow of xml files into a folder. A XML file name can look like this. It only goes up to 1005.
1001.order-asdf1234.xml
1002.order-asdf4321.xml
I want to sort the files into uniquely named folders that are not based on the file names. A example for that would be
C:\Directory Path...\Peter (All files starting with 1001 go in there)
C:\Directory Path...\John (All files starting with 1002 go there)
How can I create a batch or a powershell script to continuously sorts files into the specified folders? Since I only have 5 folders I would like to simply specify the target folders for each and not have elaborate loops but I don't know how to do that.
The easiest way is to create a lookup Hashtable where you define which prefix ('1001' .. '1005') maps to which destination folder:
# create a Hasthable to map the digits to a foldername
$folderMap = #{
'1001' = 'Peter'
'1002' = 'John'
'1003' = 'Lucretia'
'1004' = 'Matilda'
'1005' = 'Henry'
}
# set source and destination paths
$rootFolder = 'X:\Where\the\files\are'
$destination = 'Y:\Where\the\files\should\go'
# loop over the files in the root path
Get-ChildItem -Path $rootFolder -Filter '*.xml' -File |
Where-Object { $_.BaseName -match '^\d{4}\.' } |
ForEach-Object {
$prefix = ($_.Name -split '\.')[0]
$targetPath = Join-Path -Path $destination -ChildPath $folderMap[$prefix]
$_ | Move-Item -Destination $targetPath -WhatIf
}
Remove the -WhatIf safety-switch if you are satisfied with the results shown on screen
You could use a switch statement to decide on the target folder based on the first part of the file name:
$files = Get-ChildItem path\to\folder\with\xml\files -Filter *.xml
switch($files)
{
{$_.Name -like '1001*'} {
$_ |Move-Item -Destination 'C:\path\to\Peter'
}
{$_.Name -like '1002*'} {
$_ |Move-Item -Destination 'C:\path\to\John'
}
{$_.Name -like '1003*'} {
# etc...
}
default {
Write-Warning "No matching destination folder for file '$($_.Name)'"
}
}
If you change your mind about loops, my preference would be to store the mapping in a hashtable and loop over the entries for each file:
$files = Get-ChildItem path\to\folder\with\xml\files -Filter *.xml
$targetFolders = #{
'1001' = 'C:\path\to\Peter'
'1002' = 'C:\path\to\John'
'1003' = 'C:\path\to\Paul'
'1004' = 'C:\path\to\George'
'1005' = 'C:\path\to\Ringo'
}
foreach($file in $files){
$targetFolder = $targetFolders.Keys.Where({$file.Name -like "${_}*"}, 'First')
$file |Move-Item -Destination $targetFolder
}
I have 50 sub-Folders inside a Single Parent Folder.
Inside each sub folders there are multiple .txt files. I want to merge all the text files in a single sub-folder into 1 .txt file.
But I want a command so that it can be done in one go for all the subfolder, like i don't want to write command for each sub-folder.
For example:-
ABCD (Parent Folder ):-
A
B ; Here A and B are sub-folder
A\0001.txt
A\0002.txt
I want to merge and make a single text file A\0001.txt.
B\0001.txt
B\0002.txt
I want to merge both the text files in B Folder.
Can it be done in one go ?
This is probably a lot easier using powershell.
Try the following and change the basedir to the parent folder of all your subdirectories.
$basedir = "C:\Basedir"
$folderlist = Get-childitem -Path $basedir
foreach ($folder in $folderlist)
{
$dir = $folder
$outFile = Join-Path $dir "merged.txt"
# Build the file list
$fileList = Get-ChildItem -Path $dir -Filter File*.txt -File
# Get the header info from the first file
Get-Content $fileList[0] | select -First 2 | Out-File -FilePath $outfile -Encoding ascii
# Cycle through and get the data (sans header) from all the files in the list
foreach ($file in $filelist)
{
Get-Content $file | select -Skip 2 | Out-File -FilePath $outfile -Encoding ascii -Append
}
}
Maybe old but useful: this version works with folders and subfolders recursively:
$basedir = "..."
$folderlist = Get-childitem -Path $basedir -Recurse -Directory | Select-Object FullName
foreach ($folder in $folderlist)
{
Write-Host $folder.FullName
$dir = $folder.FullName
$outFile = Join-Path $basedir "merged.txt"
# Build the file list
$fileList = Get-ChildItem -Path $dir -Filter *.log | Select-Object FullName
# Get the header info from the first file
#Get-Content $fileList[0] | select -First 2 | Out-File -FilePath $outfile -Encoding ascii
# Cycle through and get the data (sans header) from all the files in the list
foreach ($file in $filelist)
{
Write-Host $file.FullName
Get-Content $file.FullName | Out-File -FilePath $outfile -Encoding ascii -Append
}
}
I have following Power Shell script I need to modify.
$filepath = "F:\feeds\Amazon\"
$temppath = $filepath+"temp.csv"
$files = ls -Path $filepath *.csv
foreach ($file in $files){
gc $file.FullName |
% { if($_.indexOf("|~|") -eq -1) {$_ -replace "`"((?:`"`"|.)*?)`"(?!`")", "|~|`$1|~|" -replace "`"`"", "`""} else {$_ -replace " ", " "}} |
sc $temppath
ri $file.fullName
rni -Path $temppath -NewName $file.fullName
}
This script loops through all .csv files in a defined folder and change the text qualifier. Now I need to change this a bit and I am stucked.
Basically my CSV files are spitted into multiple folders like. Amazon1, Amazon2, Amazon3 .. so on. Is there anything wild card match sort of things I can do here so that it looks into all folders whose name starting with Amazon?
I Don't want to loop through folders.
... The * character? Try this:
$filepath = "F:\feeds\Amazon*"
$files = ls -Path $filepath *.csv -recurse
foreach ($file in $files){
$temppath = $file.directoryName+"\temp.csv"
gc $file.FullName |
% { if($_.indexOf("|~|") -eq -1) {$_ -replace "`"((?:`"`"|.)*?)`"(?!`")", "|~|`$1|~|" -replace "`"`"", "`""} else {$_ -replace " ", " "}} |
sc $temppath
ri $file.fullName
rni -Path $temppath -NewName $file.fullName
}
Yes withe Get-child-Item Cmdlet (dir) you can use wild card match on folders :
Get-ChildItem "C:\temp\Amazon?\" -include *.csv -Recurse
# ---------------------------------------------------------
# ScriptingGamesBeginnerEvent8_PS1.ps1
# ed wilson, msft 8/21/2009
# PS1 version of HSG-08-19-09 http://bit.ly/1d8Rww
#
# ---------------------------------------------------------
Param(
[string]$path = 'C:\',
[int]$first = 50
)# end param
# *** Function Here ***
function Get-DirSize ($path){
BEGIN {}
PROCESS{
$size = 0
$folders = #()
foreach ($file in (Get-ChildItem $path -Force -ea SilentlyContinue)) {
if ($file.PSIsContainer) {
$subfolders = #(Get-DirSize $file.FullName)
$size += $subfolders[-1].Size
$folders += $subfolders
} else {
$size += $file.Length
}
}
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name Folder -Value (Get-Item $path).fullname
$object | Add-Member -MemberType NoteProperty -Name Size -Value $size
$folders += $object
Write-Output $folders
}
END {}
} # end function Get-DirSize
Function Get-FormattedNumber($size)
{
IF($size -ge 1GB)
{
"{0:n2}" -f ($size / 1GB) + " GigaBytes"
}
ELSEIF($size -ge 1MB)
{
"{0:n2}" -f ($size / 1MB) + " MegaBytes"
}
ELSE
{
"{0:n2}" -f ($size / 1KB) + " KiloBytes"
}
} #end function Get-FormattedNumber
# *** Entry Point to Script ***
if(-not(Test-Path -Path $path))
{
Write-Host -ForegroundColor red "Unable to locate $path"
Help $MyInvocation.InvocationName -full
exit
}
Get-DirSize -path $path |
Sort-Object -Property size -Descending |
Select-Object -Property folder, size -First $first |
Format-Table -Property Folder,
#{ Label="Size of Folder" ; Expression = {Get-FormattedNumber($_.size)} }
So I have this script which I got from
http://gallery.technet.microsoft.com/scriptcenter/36bf0988-867f-45be-92c0-f9b24bd766fb#content
I've been playing around with it and created a batch file to help handle the log output of this file and such. However, I'm noticing that paths with spaces in them don't get read. For example ..Documents\My Music
Get-Item : Could not find item C:\Users\MyUser\Documents\My Music.
At C:\test.ps1:32 char:80
+ $object | Add-Member -MemberType NoteProperty -Name Folder -Value (Get-It
em <<<< $path).fullname
+ CategoryInfo : ObjectNotFound: (C:\Users\MyUser\Documents\My
Music:String) [Get-Item], IOException
+ FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetIt
emCommand
On the TechNet page for the code, someone brings the issue up but no solution is given. I'm not sure how to fix it here. I've played with the $path argument, surrounding it in " " or ' ' and such.
Here is part of the batch file to execute it:
C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe -noe -command "& 'C:\test.ps1' -path "'C:\Users\MyUser\'""
Might be a bit late for answer here, but, as Aaron mentioned, this is not due to spaces in the path.
If you read the documentation for Get-Item cmdlet, there is a -Force switch, which allows the cmdlet to get items that cannot otherwise be accessed, such as hidden items.
Moreover, it seems from your code that you are not expecting to pass a wildcard pattern to the cmdlet, so instead of (Get-Item $path).FullName you should use
(Get-Item -force -LiteralPath $path).FullName
That should resolve this issue.
It's not the spaces in the path. If it was, the error would say path C:\Users\MyUser\Documents\My couldn't be found. Get-ChildItem and Get-Item behave... strangely... with certain files/directories, returning errors like you're seeing. That's why Get-ChildItem has an -ErrorAction SilentlyContinue parameter on it. I would add the same to the call to Get-Item, i.e. change
(Get-Item $path).FullName
to
(Get-Item $path -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
or even forgo the call to Get-Item completely:
$path
As suggested by TheTrowser in a comment above: The problem may be resolved if you replace the double-quotes with single quotes surrounding the file directory with spaces. This is what solved it for me.
Using the command below didn't work for me.
get-item 'some path with two spaces.txt'
Enclosing the filename in double quotes within the single quotes, forces Powershell to use the filename as written.
get-item '"some path with two spaces.txt"'
Note: I'm totally cringing at my origal message (cleaned up a bit above). Below is a better example of what I was seeing.
$exampleA = "c:\temp\weird path\blah.txt"
$exampleB = "c:\temp\normal path\blah.txt"
# Works
get-item '$exampleA'
get-item $exampleB
# Fails
get-item $exampleA