i have a problem : in files name i have to write their lengths
for example qwerty.tmp → qwerty_12039.tmp ! please help
use:
get-childitem c:\Folder | rename-item -NewName {$_.name -replace ".tmp", $_length ".tmp"}
but it doesn't work
You left '.' there. Also: I would use BaseName instead:
ls C:\folder | Rename-Item -NewName { $_.BaseName + $_.Length + '.tmp' }
Related
I am trying (as so many others) to batch rename files in a folder, by adding a counter to the front of the filename with leading zeros.
Here is what I have:
b.txt
c.txt
...
zzz.txt
Here is what I want:
001_b.txt
002_c.txt
...
893_zzz.txt
My code so far:
$originalFiles = Get-ChildItem "C:\Users\abc\" -Filter *.txt
$i = 1
ForEach ($originalFile in $originalFiles) {
Rename-Item -Path $originalFile.FullName -NewName (($originalFile.Directory.FullName) + "\" + $i + $originalFile.Name)
$i++
}
I am missing the underscore between the the number and the filename. And I am missing the leading zeros.
Any suggestions are welcome.
Sorry for this basic question, this is my first PowerShell experience.
This should do the trick:
$MyPath = "C:\Users\abc\"
$i=1
Get-ChildItem -Path $MyPath -Filter "*.txt" | Sort-Object | ForEach-Object {
Rename-Item -Path $_.FullName -NewName (Join-Path -Path $_.Directory.FullName -ChildPath "$('{0:d3}' -f $i)_$($_.Name)")
$i++
}
Keep in mind that if you will have 1000 or more files, you will need more than 3 digits
I'm trying to create a script to rename a file that matches a given filename, with a wildcard character. e.g.
I have a folder containing the following files:
201412180900_filename_123.log
201412181000_filename_123.log
201412181100_filename_456.log
filename_789.log
I want to scan through this folder, and append the current time to the start of any file starting with the word 'filename'
I have the following so far:
$d = Get-Date -format "yyyyMMddHHmm"
$dir = "C:\test"
$file = "filename*.log"
get-childitem -Path "$dir" | where-object { $_.Name -like "$file" } | rename-item -path $_ -newname $d."_".$_.name
but it doesn't work.
As I see it the individual sections 'should' work from my reading of the documentation, but clearly something is wrong. If someone can point it out it would be appreciated.
We're getting closer. It would appear that -path in the rename-item section needs to be $dir$_ as $_ (seemingly) only contains the filename. (The get-help example suggests it needs to be the full path and filename)
If I take out the rename-item section and replace it with %{write-host $d"_"$_} it gives the correct new filename
However, simply placing this into rename-item section still doesn't update the filename.
rename-item -path $dir$_ -newname $d"_"$_
SUCCESS
the correct syntax appears to be:
get-childitem -Path "$dir" | where-object { $_.Name -like "$file" } | %{rename-item -path $dir$_ -newname $d"_"$_}
The missing element was the %{ ... } surrounding the rename-item section which enabled me to reference $_
$d = Get-Date -format "yyyyMMddHHmm"
$dir = "C:\test"
$file = "filename*.log"
get-childitem -Path $dir | where-object { $_.Name -like $file } | %{ rename-item -LiteralPath $_.FullName -NewName "$d`_$($_.name)" }
This should work, assuming that the errors were relating to "Cannot bind argument to parameter 'Path'", and the NewName string.
Issues included:
Not being able to reference $_ when not in a foreach style block (see here)
The Concatenation issue raised by #alroc
You could, instead of passing the pipeline object to a Foreach-Object, pass directly to the Rename-Item - but I'm unsure quite how to reference the name of the object for the -NewName parameter.
I don't recall . being a string concatenation operator in PowerShell (I may be wrong). Try this:
rename-item -path $_ -newname "$d_$($_.name)"
Or this
rename-item -path $_ -newname ($d + "_" + $_.name)
Or even this
rename-item -path $_ -newname ({0}_{1} -f $d,$_.name)
See the answers here
Yet another way to do it without using foreach or %, but a script block instead:
get-childitem -Path "$dir" -filter $file | rename-item -newname { $d + "_" + $_.name }
See the examples in the doc for rename-item: https://msdn.microsoft.com/en-us/powershell/reference/3.0/microsoft.powershell.management/rename-item There's a -replace operator too, but it can't use wildcards? Oh, you don't need wildcards:
get-childitem -Path "$dir" -filter $file | rename-item -newname { $_.name -replace 'filename',($d + '_filename') }
I have files like this.
[mix]aaaa.flv
[mix]aaaa.mpv
[mix]aaaa.ogv
[mix]aaaa.webm
[mix]bb.flv
[mix]bb.mpv
[mix]bb.ogv
[mix]bb.webm
...
I just need to remove "[mix]" from the file names.
I use this command, but failed
Dir | Rename-Item –NewName { $_.name –replace "[mix]", "" }
Error says
Rename-Item : 'Microsoft.PowerShell.Core\FileSystem::C:\Users\Desktop\[mix]aaaa.mp4'에 항목이 없으므로 이름을 바꿀 수 없습니다.
위치 줄:1 문자:18
+ Dir | Rename-Item <<<< –NewName { $_.name –replace “[mix]“,”” }
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand
There's korean in error code, it might say : Can't change name, there is no item at 'Microsoft.PowerShell.Core\FileSystem::C:\Users\Desktop\[mix]aaaa.mp4'
And I don't understand what I'm doing wrong. I used to change file names with this command.
I think this is a known bug with Rename-Item and powershell 2.0
What I did was to use Move-Item instead, you should be able to use the following (tested on powershell 2.0):
Dir | Move-Item -Destination {$_.Name -replace "\[mix\]", ""}
I was able to make this work. Remember that [ and ] are regex metacharacters and need to be escaped:
Dir | Rename-Item -NewName {$_.Name -replace "\[mix\]",""}
I'm trying to write a very simple PowerShell script to give me the total number of items (both files and folders) in a given folder (c:\MyFolder). Here's what I've done:
Write-Host ( Get-ChildItem c:\MyFolder ).Count;
The problem is, that if I have 1 or 0 items, the command does not work---it returns nothing.
Any ideas?
You should use Measure-Object to count things. In this case it would look like:
Write-Host ( Get-ChildItem c:\MyFolder | Measure-Object ).Count;
or if that's too long
Write-Host ( dir c:\MyFolder | measure).Count;
and in PowerShell 4.0 use the measure alias instead of mo
Write-Host (dir c:\MyFolder | measure).Count;
I finally found this link:
https://blogs.perficient.com/microsoft/2011/06/powershell-count-property-returns-nothing/
Well, it turns out that this is a quirk caused precisely because there
was only one file in the directory. Some searching revealed that in
this case, PowerShell returns a scalar object instead of an array.
This object doesn’t have a count property, so there isn’t anything to
retrieve.
The solution -- force PowerShell to return an array with the # symbol:
Write-Host #( Get-ChildItem c:\MyFolder ).Count;
If you need to speed up the process (for example counting 30k or more files) then I would go with something like this..
$filepath = "c:\MyFolder"
$filetype = "*.txt"
$file_count = [System.IO.Directory]::GetFiles("$filepath", "$filetype").Count
Only Files
Get-ChildItem D:\ -Recurse -File | Measure-Object | %{$_.Count}
Only Folders
Get-ChildItem D:\ -Recurse -Directory | Measure-Object | %{$_.Count}
Both
Get-ChildItem D:\ -Recurse | Measure-Object | %{$_.Count}
You can also use an alias
(ls).Count
Recursively count files in directories in PowerShell 2.0
ls -rec | ? {$_.mode -match 'd'} | select FullName, #{N='Count';E={(ls $_.FullName | measure).Count}}
In powershell you can to use severals commands, for looking for this commands digit: Get-Alias;
So the cammands the can to use are:
write-host (ls MydirectoryName).Count
or
write-host (dir MydirectoryName).Count
or
write-host (Get-ChildrenItem MydirectoryName).Count
To count the number of a specific filetype in a folder.
The example is to count mp3 files on F: drive.
( Get-ChildItme F: -Filter *.mp3 - Recurse | measure ).Count
Tested in 6.2.3, but should work >4.
I have this issue where I must replace the string "121212" in all text files with the name of it's parent folder (e.g. if the parent folder is named "123456" than the string "121212" should be replaced with "123456")
I thought I figured out how to do this with the following commands:
PS E:\testenvironment> $parent=get-childitem -recurse | where {$_.FullName -match "[testenvironment]\\\d{6}$"} | foreach {$_.Name}
PS E:\testenvironment> $parent
123456
456789
654321
987654
PS E:\testenvironment> $files=get-childitem -recurse | where {$_.FullName -match "\\\d{6,6}\\AS400\\test3.txt$"} | foreach {$_.FullName}
PS E:\testenvironment> $files
E:\testenvironment\123456\AS400\test3.txt
E:\testenvironment\456789\as400\test3.txt
E:\testenvironment\654321\AS400\test3.txt
E:\testenvironment\987654\AS400\test3.txt
PS E:\testenvironment> foreach ($file in ($files)) {Get-Content "$file" | foreach-Object {$_ -replace "121212", "($name in ($parent))"} | set-content "$file"}
But I get this message :
Set-Content : The process cannot access the file 'E:\testenvironment\123456\AS400\test3.txt' **because it is being used by another process**.
At line:1 char:127
+ foreach ($file in ($files)) {Get-Content "$file" | foreach-Object {$_ -replace "121212", "($name in ($parent))"} | set-content <<<< "$file"}
+ CategoryInfo : NotSpecified: (:) [Set-Content], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand
(... i receive this for every test3.txt file ofcourse ...)
I cannot figure out how to get the "current memory" into a new variable so, that the file (that would currently be in the memory) can be overwritten with the new data.
Provided all of your text files are in the directory structure you've posted, the following will get the job done:
get-childitem $testEnvPath -recurse -filter "*.txt" | foreach{
$content = Get-Content $_.fullname
#To get the file's grandparent directory name ($_.fullname -split '\\')[-3]
$content -replace "121212", ($_.fullname -split '\\')[-3] |
set-content $_.fullname
}
Note that to 'move' to the next file / directory in memory, the enumeration of those items must be inside of the foreach statement whereas you were enumerating them outside.
Hope that helps.