keep 100 newest file in a directory - windows script porting - windows

Hi: I have a cronjob in linux that keeps last 100 files in a directory, now I need to port it on windows.
my linux job is the following:
# sort by time, 1 per line | get files over 100th | delete those
$ ls -1t \my\path\tmp | tail --lines=+100 | xargs rm -f
and it's run once per day
Now I'm doing
REM get files olther than 2D, delete
forfiles /d -2 /p "C:\my\path\tmp" /c "cmd /c Del #path"
that just deletes files older than 2 days, but I'd like not to delete files if total number is not too big (<100)

I realize this is not as cryptic and magical as using a for loop, but it works. When you are satisfied that the correct files will be deleted, remove the -WhatIf from the Remove-Item cmdlet.
powershell -NoLogo -NoProfile -Command ^
"Get-ChildItem -File |" ^
"Sort-Object -Property LastWriteTime -Descending |" ^
"Select-Object -Skip 100 |" ^
"Remove-Item -WhatIf"
Powershell runs on Linux and Mac as well. https://github.com/powershell/powershell

Related

Remove white spaces in file names and change file names from lower to upper case

In Windows, I want to remove white spaces from file names and change the lower case to upper case.
file 1.txt --> FILE1.TXT
File 2.txt --> FILE2.TXT
Test 1.txt --> TEST1.TXT
I tried something like this (which is not working) on command prompt
rename "*.txt" "*.TXT" # Works
rename "file*.txt" "FILE*.TXT"
rename "Test*.txt" "TEST*.TXT"
As #Mofi said, cmd is not well equipped to do this. If you are on a supported Windows system, powershell was installed with it. When you are confident that the files would be renamed as you expect, remove the -WhatIf from the Rename-Item command.
Get-ChildItem -File | Rename-Item -NewName { $_.Name.ToUpper() } -WhatIf
If you are desperate to run this from a cmd prompt or batch-file, this could be used.
powershell -NoLogo -NoProfile -Command ^
Get-ChildItem -File ^| Rename-Item -NewName { $_.Name.ToUpper() } -WhatIf

How can I sort files based on their last updated time using "dir" command in Windows

I am using "dir" command on the command line prompt in Windows 10. I've tried the following:
c:\my_folder> dir /s /b
but, the above command is not displaying the files according to the last updated time of files.
Open a powershell console and enter this command:
Get-ChildItem | Sort-Object -Property LastWriteTime
If you want descending order, then use:
Get-ChildItem | Sort-Object -Property LastWriteTime -Descending

How do I execute a command one after another, each at a separate time?

In Windows Terminal, I am able to execute several commands at the same i.e.:
echo %time% && timeout 3 && echo %time%
However, when executing the above command, It will result in something like:
9:27:57.41
0 秒待っています。続行するには何かキーを押してください ... (My operating system
is Japanese)
9:27:57.41
As you can see, echo %time% is not executed at a different time even though there was a 3 second timeout in between.
How would I separate these two executions?
The End goal here is to measure the the time it takes to perform dir /s C:\.
I tried different things such as:
Powershell -C "Measure-Command {cmd /c dir /s C:\ | Output-Default}" > test.txt
or from Powershell:
Measure-Command{cmd /c dir /s C:\ | Output-Default} > test.txt
But neither of these commands result in the same result I get from running just dir /s C:\ in Terminal. There are differences in time and file count.
I thought I could try:
echo %time% >> test & dir /s C:\ >> test & echo %time% >> test
as an alternative to the Measure-Command but that is not the case...
Something similar can easily be done in linux i.e date +%N && sleep 1 && date +%N or date +%s && sleep 1 && date +%s so why not the almighty Powershell? (a bit of sarcasm)
Any other alternatives I could try or shedding some light to how this all works would help a ton.
EDIT:
With the help from Drew, I was able to do this with the Get-ChildItem method in Powershell. However, this only took a fraction of the time it would take with dir /s. The key goal here is to measure how long it takes with dir so this is mandatory.
EDIT2:
Seems like writing the standard output to the terminal was taking time and not the command itself. Redirecting the output to a File or > NUL was much faster.
Kind regards.
So DIR /S will scan all files in the directory and sub-directory. The PowerShell equivalent of this is -File and -Recurse. So putting these into practice, the entire PowerShell command would be:
Measure-Command -Expression {
Get-ChildItem -Path "C:\" -Recurse -File
} | Out-File C:\test.txt
This will only give you the time taken, not the amount of files. To get the amount of files, you will need to change it up a little.
Measure-Command -Expression {
(Get-ChildItem -Path "C:\" -Recurse -File).Count | Out-File C:\FileCount.txt
} | Out-File C:\test.txt
Alternatively, you could run this and get something a little nicer. and each task is split up on a new line.
$Path = "C:\"
$StartTime = Get-Date
$FileCount = (Get-ChildItem -Path $Path -Recurse -File).Count
$EndTime = Get-Date
$TimeTaken = New-TimeSpan –Start $StartTime –End $EndTime
"Found $FileCount files in $Path which took $($TimeTaken.Seconds) Seconds" | Out-File C:\test.txt

Copy all .jpg from subfolders to a single folder by cmd

I have a folder that has 148 folders in it, and in each of these folders they have a .jpg file. I need to get all these .jpg and put in a single folder
each folder is at least 1 .jpg
I can do this on Linux as well
`#!/bin/bash
for file in `find source -name * .jpg`;
of the mv "$ file" Destination;
done;
but I can not play this in Windows. Only the find command that I can reproduce the same result: dir /S /B *.jpg
for /r %f in (*.jpg) do move %f %destination%
Note: This is the interactive version. In a command script, you need to protect the %f's from too-early variable substitution.
for /r %%f in (*.jpg) do move %%f %destination%
Another way to do it using PowerShell. When you see that the files are being moved as you expect, remove the WhatIf from the Move-Item cmdlet.
Get-ChildItem -Recurse -File -Filter '*.jpg' |
ForEach-Object { Move-Item -Path $_.FullName -Destination 'C:\the\other\dir' -WhatIf }
You can run this in a cmd.exe shell or .bat script.
powershell -NoLogo -NoProfile -Command ^
"Get-ChildItem -Recurse -File -Filter '*.jpg' |" ^
"ForEach-Object { Move-Item -Path $_.FullName -Destination 'C:\the\other\dir' -WhatIf }"
The easiest way to achieve this is in Windows is to open to root folder with the Windows Explorer at which you want to start searching all the elements. Then go to the small input field for searching and enter *.jpg the result will show all the jpg in the root folder and all subfolders. Then you can simply copy and paste the files to your destination folder.

Bat script to retrieve folder size (windows)

I need to write a script .bat that give me the free space of a certain disk and the detail of all folders with the relative dimension and write it in a simple text file (just to check the distribution of used space).
Thanks a lot in advance!
dir /a /s | findstr /b /c:" " > file.txt
The FileSystemObject can do this for you. It is accessible from PowerShell (among other sources).
PowerShell -NoProfile -Command "$fso = New-Object -COMObject Scripting.FileSystemObject; Get-ChildItem YOUR_ROOT_DIRECTORY -Recurse -Directory | %% { $f = $fso.GetFolder($_.FullName); '{0},{1}' -f $f.Size,$_.FullName };"

Resources