Renaming with last save date - windows

I have a problem with renaming files. My goal is renaming files with the last saving date. Unfortunately, by a wrong modification, the last modified dates are not the same as the last save date.
I tried to solve with this code in Powershell:
Get-ChildItem | Rename-Item -NewName {$_.basename + " " + $_.LastWriteTime.ToString("yyyy-MM-dd") + $_.Extension}
It would be great if the code put the last save date in the end of the filename. But I cant modify it to be correct.
I can sort the files in the File Explorer by last save date. I need these dates to be put in the of the filename.
Anyone could help me solve this?

Try using Get-Date to convert the file's LastWriteTime to a string.
Get-ChildItem | Rename-Item -NewName {$_.basename + " " + (Get-Date $_.LastWriteTime -Format "yyyy-MM-dd") + $_.Extension}

Related

How to rename multiple files with existing Unix time in file name?

While I know how I would do this in PHP, it doesn't make sense to install IIS, install PHP just to get this done.
I have a folder D:\Data that has several subfolders in it. These folders contain files which are backups created with a program that adds a time stamp to the name to allow multiple copies of the file to be backed up.
These files need to be named:
usera.dat
But they are named currently:
usera.dat.17383947323.dat
In PHP, I would load the file name into a string, explode the string on ".", then rename the file using the [0] and [3] elements to rename the file, i.e. without the loop to read the directories:
$filename = $existing_file
$explodename = explode(".",$filename);
$newfilename = $explodename[0] . "." . $explodename[3];
rename($filename, $newfilename);
Does anyone have any recommendation on how to do this with PowerShell or a batch file looping over all the subfolders in D:\Data?
Right now I am manually editing each file removing the extra Unix time stamp.dat part.
Translating this from PHP to PowerShell should be a breeze, let's give it a try:
$files = Get-ChildItem -Filter *.dat.*.dat
foreach($file in $files){
$filename = $file.Name
$explodename = $filename.Split('.')
$newfilename = "$($explodename[0]).$($explodename[3])"
Rename-Item $file.FullName -NewName $newfilename
}
As shown above:
PowerShell does not have an explode() function, but we can use the String.Split() method on any string and get a string array back
. is not a string concat operator in PowerShell, but we can use subexpressions $(...) inside an expandable string.
The Rename-Item cmdlet will take care of renaming
A more PowerShell-idiomatic solution would be to leverage the pipeline though:
Get-ChildItem -Filter *.dat.*.dat | Rename-Item -NewName {$explodename = $_.Name.Split('.');"$($explodename[0]).$($explodename[3])"}
You could also use a regex pattern in place of the Split() method and string concatenation:
Get-ChildItem -Filter *.dat.*.dat | Rename-Item -NewName {$_.Name -replace '^([^\.])\..*\..*\.([^\.])$','$1.$2'}
Or do the concatenation with the -join operator:
Get-ChildItem -Filter *.dat.*.dat | Rename-Item -NewName {$_.Name.Split('.')[0,3] -join '.'}
Whatever you fancy, Get-ChildItem and Rename-Item are definitely the commands you'd want to use here
One-liner in batch from the prompt:
#FOR /r "U:\sourcedir" %a IN (*) DO #FOR %b IN ("%~na") DO #FOR %c IN ("%~nb") DO #IF "%~xc" neq "" ECHO REN "%a" "%~nxc"
Note: echoes the rename command for testing. Remove the echo keyword after testing to execute the rename.
I used u:\sourcedir as a test directory.
Translation: for each filename in the subtree (%%a) take the name part only and assign to %%b, repeat for %%c and if there was no extension part in the result, then do the rename.
Mathias R. Jessen's answer contains many helpful pointers, but it seems that the simpler and more robust approach would be to simply drop the final 2 extensions, assuming that all files in the folder tree have these 2 extraneous extensions:
Get-ChildItem -File -Recurse D:\Data |
Rename-Item -NewName { $_.Name -replace '(\.[^.]*){2}$' }

Insert timestamp into filename when exporting into .csv

I am trying to insert the timestamp into the filename of an output file generated by PowerShell scrip.
So instead of filelist.csv, it names the output file with the actual timestamp (of the outpufile's modification time), like YYYYMMDD_HHMMSS_filelist.csv.
Get-childitem -recurse -file | select-object #{n="Hash";e={get-filehash -algorithm MD5 -path $_.FullName | Select-object -expandproperty Hash}},lastwritetime,length,fullname | export-csv filelist.csv -notypeinformation
Any suggestions as to what is the missing code from the above line for timestamping the output file?
Change:
export-csv filelist.csv -notypeinformation
To:
Export-Csv "$((Get-Date).ToString("yyyyMMdd_HHmmss"))_filelist.csv" -NoTypeInformation
Edit - .ToString() and -UFormat, generally
When using .ToString() or -Format/-UFormat, you are passing a DateTime object and getting back a formatted string. In both cases you have to specify the format of the string you are after. The ways this format is specified differs.
Check out this list of .NET format strings that can be used with ToString()/-Format. Note how e.g. MM is months 01-12, M is months 1-12 and mm is minutes 00-59.
-UFormat is documented to use UNIX formatting. I'm not familair with this at all, but the Notes section goes into detail. You can see here %m is month while %M
In your file name, do as follows:
Export-Csv -Path "$(Get-Date -UFormat '%Y%m%d_%H%M%S')_filelist.csv" -NoTypeInformation

Windows : How to list files recursively with size and last access date?

I need a simple way to create a list of all files in a certain folder. (recursively)
Each file must be in a single line. I also need the file size and the last access date in the same line, separated by a special character.
The output (textfile) should look like this:
c:\folder\file1.txt|400|2012-11-12 15:23:08
c:\folder\file2.txt|200|2012-11-12 15:23:08
c:\folder\file3.txt|100|2012-11-12 15:23:08
c:\folder\sub folder\file4.txt|500|2012-11-12 15:23:08
'Dir' seems not to be an option, because the German Special characters get messed up that way. (öäüß)
Powershell handles the special characters well, but I couldn't make it so that the information for one file ends up in a single line:
get-childitem D:\temp -rec | where {!$_.PSIsContainer} | foreach-object -process {$_.FullName, $_.LastWriteTime, $_.Length}
try this:
get-childitem D:\temp -rec | where {!$_.PSIsContainer} |
select-object FullName, LastWriteTime, Length | export-csv -notypeinformation -delimiter '|' -path file.csv

replacing text in app.config using powershell script

I am trying a simple replace script to replace text in a app.cofig file. But it just processed and do nothing:
$old = 'Z:\gene'
$new = 'z:\gene\scripts'
Get-ChildItem z:\gene\scripts\Test\App.config -Recurse | Where {$_ -IS [IO.FileInfo]} |
% {
(Get-Content $_.FullName) -replace $old,$new | Set-Content $_.FullName
Write-Host "Processed: " + $_.FullName
}
Any Idea what I am doing wrong. As same script works fine for .txt file
Thanks
App.config is xml formatted but it's a text file as well, it should work the same. My guess is that you have a different values that your working on and they are not hitting. If you rename the file to app.txt does it work ? You might also consider using nant xmlpoke if you are running from nant script.

Command or Script to rename multiple files in windows

I have around 400 movies on my hard-disk, but names of those movies contains dots or underscore in between like "wrong_turn.mkv" or "wrong.turn.mkv". I just want to remove these dots or special characters from the file name and keep the extension as it as.
Any Command Line command or Powershell/Python or any other script for windows? Thanks.
If the two files you have reside in the same directory then removing _ from the first file will work, but when you'll try to remove the dot from the second file it will fail cause it'll have the same name as the first one. Maybe that's an edge case, so here's the basic solution:
Get-ChildItem -Filter *.mkv | Rename-Item -NewName {($_.BaseName -replace '\.|_') + $_.Extension}
In PowerShell you can use Rename-Item with a script block that determines the new name.
dir -Recurse -Include *.mkv | Rename-Item -NewName { expression to determine new name }
The expression within the script block can use $_ to reference the current FileInfo object.
More concretely:
dir -Recurse -Include *.mkv | Rename-Item -NewName { $_.Name.Replace('_', ' ') }
Use Rename-Item -WhatIf until you get it right.

Resources