Övervaka mapp och byta namn på filer vid ändring

Permalänk
Medlem

Övervaka mapp och byta namn på filer vid ändring

Jag är lite nyfiken på om det finns en metod för att åstadkomma följande.

1. Jag sparar en fil i en mapp. Filen kan redan finnas där, den sparas helt enkelt om och får därmed ett nytt "modified date".
2. När filen är sparad, dvs när "modified date" uppdateras, byt då namn på filen så att den får dagens datum som ett prefix.

Det skulle exempelvis kunna finnas en fil som heter fil.doc i denna mapp. Jag öppnar filen, gör ändringar och sparar den. Jag skulle då vilja att filnamnet automatiskt ändrades till 2024-01-07 fil.doc efter att jag sparat den. Om jag sen går in dagen efter, gör ändringar och sparar igen så vill jag att filnamnet automatiskt ändras till 2024-01-08 fil.doc.

Går detta att göra och hur gör jag det smidigast?

Permalänk
Medlem

Jag är inte så kunnig på Windows, men slänger ut några köttben iallafall:

Kika på antingen "Task Scheduler" eller monitorering med "powershell". Länkarna kan ge lite ideer till flera sökningar.

https://superuser.com/questions/226828/how-to-monitor-a-folde...
Monitorering av en fil eller katalog? (/MON:x och /MOT:x)
https://serverfault.com/questions/55733/the-job-and-monitorin...
https://www.pdq.com/blog/hitchhikers-guide-to-robocopy/
Hur man döper om en fil till aktuellt datum.
https://stackoverflow.com/questions/4984391/cmd-line-rename-f...

Permalänk
Medlem

Tack!

Jag hittade också Watch 4 Folder som kan övervaka en mapp och sedan utföra exempelvis ett batch-script när någonting händer med filen i fråga.

Jag är dessvärre helt lost när det kommer till batch-script, så vore oerhört tacksam om någon med mer kunskap kunde hjälpa till. Skulle inte tro att det är jätteavancerat, men vad vet jag.

Har gjort lite tester i det scenario som jag vill använda filerna för och kommit fram till att det förmodligen är bäst med detta flöde:

1. Filerna kommer vara strukturerade som "ord_YYYYMMDD_HHMMSS.txt". Det är bara filer med .txt som detta ska göras på.
2. Pathen till filen kommer finnas som variabel %1 i scriptet.
3. Scriptet ska därefter duplicera originalfilen och döpa den nya filen till "ord_YYYYMMDD_HHMMSS.txt" (där "YYYYMMDD_HHMMSS" är det nuvarande datumet och tiden) och sedan radera den gamla filen.
4. Om originalfilen skulle sakna datum/tid (alltså bara "ord.txt") så ska samma sak göras med denna, dvs duplicera filen, ta "ord"-delen av filnamnet och appenda datum/tid.

Antar att scriptet kommer behöva lokalisera "ord" i filnamnet och spara denna i en variabel som sedan används för att duplicera och lägga till datum/tid efteråt.

Permalänk
Hedersmedlem

Om jag inte missar något så bör detta script fungera.

Spara som typ "rename.ps1" och säg till programmet att köra "powershell rename.ps1" eller dylikt; förhoppningsvis så tar den argument, annars kan du testa att bara köra ps1-filen direkt.

$arg = $args[0] $currentDate = Get-Date -format "yyyyMMdd_HHmmss" if ($arg -match '\d{8}_\d{6}') { $newName = $arg -replace '\d{8}_\d{6}', $currentDate } else { $newName = $arg -replace ".txt", "_$($currentDate).txt" } Move-Item $arg $newName

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem
Skrivet av Thomas:

Om jag inte missar något så bör detta script fungera.

Spara som typ "rename.ps1" och säg till programmet att köra "powershell rename.ps1" eller dylikt; förhoppningsvis så tar den argument, annars kan du testa att bara köra ps1-filen direkt.

$arg = $args[0] $currentDate = Get-Date -format "yyyyMMdd_HHmmss" if ($arg -match '\d{8}_\d{6}') { $newName = $arg -replace '\d{8}_\d{6}', $currentDate } else { $newName = $arg -replace ".txt", "_$($currentDate).txt" } Move-Item $arg $newName

Tack för detta!

Förlåt min okunskap, men jag får inte scriptet att köra. Får följande felmeddelande:

cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170. At line:1 char:1 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : SecurityError: (:) [], PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess

Tolkar jag det rätt att jag behöver tillåta att script körs någonstans i systemet?

Permalänk
Medlem

Kommer förresten originalfilen att tas bort i ditt script? Jag kunde inte se något i koden som verkade ta bort, men det kanske sker per automatik?

Permalänk
Hedersmedlem

Just ja, jag glömde bort det där.
För att man ska kunna köra Powershell-script så måste man först tillåta det. Det är för att folk inte ska skapa malware och liknande och lura folk att köra det.
Det görs genom att du söker på Powershell i startmenyn, högerklickar och kör som administratör, och i den kör:

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser

Sedan bör scriptet köras.

Originalet tas bort oavsett om den hade datum eller inte, antog att det var meningen. Eftersom kopiera + ta bort original är samma som flytta så använde jag Move-File.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem
Skrivet av Thomas:

Just ja, jag glömde bort det där.
För att man ska kunna köra Powershell-script så måste man först tillåta det. Det är för att folk inte ska skapa malware och liknande och lura folk att köra det.
Det görs genom att du söker på Powershell i startmenyn, högerklickar och kör som administratör, och i den kör:

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser

Sedan bör scriptet köras.

Originalet tas bort oavsett om den hade datum eller inte, antog att det var meningen. Eftersom kopiera + ta bort original är samma som flytta så använde jag Move-File.

Aha. Är det en dum idé att aktivera? Öppnar det upp för malware?

Jag testade i vilket fall och får följande:

Move-Item : Cannot find path 'C:\Users\Tobias\No' because it does not exist.

Vilket beror på att mappen som filen ligger i heter "No screen", så mellanrummet skapar problemet. Jag skriver pathen med citattecken, så det borde inte behöva escapeas, men jag kanske missar något?

Permalänk
Hedersmedlem

Så blir det också ja... debugging via forum är inte optimalt.
Jag är inte van vid Powershell egentligen, hade hellre kört Python, men det är inte förinstallerat så då måste man hitta workarounds för det istället.

Det är bara att lägga till citattecken runt argumenten på sista raden, dvs ersätt sista raden med:

Move-Item "$arg" "$newName"

Jag tror inte det ska var någon direkt fara med malware, fast det verkar gå att ändra detta vid körning istället (vilket dock visar att det inte ger någon direkt säkerhet att "begränsa" ExecutionPolicy!), genom att köra "powershell -ExecutionPolicy Bypass filnamn.ps1".
Om du vill skulle du därmed kunna ändra tillbaka ExecutionPolicy med kommandot från tidigare inlägget, fast sätt den till "Restricted" (som är standard) istället för "Unrestricted".

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem

Hmm. Jag får samma error även när jag lägger till citattecken runt argument på sista raden.

Fattar att det är svårt att debugga såhär, så jag kan kolla vidare och försöka lösa det själv tills vidare.

Permalänk
Medlem

Du måste skriva hela sökvägen inom ""

"C:\Users\Tobias\No screen\fil.abc"

Lägg in hela scriptet här så kan vi nog lösa det

Visa signatur

5700x3D | RTX 2060 Super | 2 TB M.2 | 32 GB RAM | Gigabyte DS3H| 750 WATT

Permalänk
Medlem

Beroende på tillvägagångssättet för hur filen skapas så kommer antagligen Windows att bråka.

Testfall
Förutsättningar: Tom målkatalog.
1) Skapa fil i önskat program, spara. Kör scriptet innan programmet som skapade filen har stängt filen.
2) Om 1 får förväntat resultat, spara igen (utan att ha stängt filen).
Förväntat resultat: En fil i målkatalogen, med den senaste sparningens datum och tid.

Permalänk
Hedersmedlem

Aha, felet är utanför scriptet (eller på rad 1, beroende på), tänkte inte ens på det. Kan man ange argument själv i det andra programmet, eftersom du nämnde %1 förut? Testa isåfall "%1" MED citattecken runt, så borde $args[0] innehålla hela sökvägen även om det är mellanslag i.

Om inte det heller funkar så testa "'%1'" (" på utsidan och ' inuti); den varianten funkar från cmd, men jag tror att det är cmd som gör att det krävs dubbla uppsättningar.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem
Skrivet av FX9:

Du måste skriva hela sökvägen inom ""

"C:\Users\Tobias\No screen\fil.abc"

Lägg in hela scriptet här så kan vi nog lösa det

Såhär ser scriptet ut nu:

$arg = $args[0] $currentDate = Get-Date -format "yyyyMMdd_HHmmss" if ($arg -match '\d{8}_\d{6}') { $newName = $arg -replace '\d{8}_\d{6}', $currentDate } else { $newName = $arg -replace ".txt", "_$($currentDate).txt" } Move-Item "$arg" "$newName"

Jag kör det såhär:
powershell C:\Users\Tobias\Documents\rename_with_date.ps1 "C:\Users\Tobias\No screen\test.txt"

Så jag har argumentet med citattecken åtminstone.

Permalänk
Medlem
Skrivet av Thomas:

Aha, felet är utanför scriptet (eller på rad 1, beroende på), tänkte inte ens på det. Kan man ange argument själv i det andra programmet, eftersom du nämnde %1 förut? Testa isåfall "%1" MED citattecken runt, så borde $args[0] innehålla hela sökvägen även om det är mellanslag i.

Om inte det heller funkar så testa "'%1'" (" på utsidan och ' inuti); den varianten funkar från cmd, men jag tror att det är cmd som gör att det krävs dubbla uppsättningar.

I programmet kan man ange vad argumentet ska bestå av, i mitt fall filnamnet på filen som ändrats. Så om jag då väljer en .bat-fil som programmet ska köra, där den skickar med det som argument, så får jag pathen till filen i fråga som %1 i scriptet.

För nu så har jag testat att köra ditt script manuellt i PowerShell, bara för att se att scriptet fungerar innan jag aktiverar det i programmet. Så då kör jag helt enkelt:

powershell C:\Users\Tobias\Documents\rename_with_date.ps1 "C:\Users\Tobias\No screen\test.txt"

Permalänk
Hedersmedlem
Skrivet av toge:

För nu så har jag testat att köra ditt script manuellt i PowerShell, bara för att se att scriptet fungerar innan jag aktiverar det i programmet. Så då kör jag helt enkelt:

powershell C:\Users\Tobias\Documents\rename_with_date.ps1 "C:\Users\Tobias\No screen\test.txt"

Fungerar det då?
Jag gjorde samma fast från cmd, då fick jag använda båda typerna av citattecken runt, antagligen för att cmd sväljer de ena och powershell de andra.

Eftersom programmet bara ska ha ett argument så borde du kunna ersätta första raden i scriptet med detta och slippa strulet:

$arg = $args -join " "

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem
Skrivet av toge:

I programmet kan man ange vad argumentet ska bestå av, i mitt fall filnamnet på filen som ändrats. Så om jag då väljer en .bat-fil som programmet ska köra, där den skickar med det som argument, så får jag pathen till filen i fråga som %1 i scriptet.

För nu så har jag testat att köra ditt script manuellt i PowerShell, bara för att se att scriptet fungerar innan jag aktiverar det i programmet. Så då kör jag helt enkelt:

powershell C:\Users\Tobias\Documents\rename_with_date.ps1 "C:\Users\Tobias\No screen\test.txt"

Jag testade nu att köra

powershell C:\Users\Tobias\Documents\rename_with_date.ps1 "'C:\Users\Tobias\No screen\test.txt'"

Alltså med "''" runt argumentet, och det fungerade klockrent! Ett problem, som jag tror att jag löst (även om jag är osäker på om det är så man brukar göra) är att programmet förväntar sig en .bat-fil. Så jag skapade en bat-fil som ser ut såhär:

@echo off powershell.exe -File "%~dp0rename_with_date.ps1" %1

Som då kör PowerShell-scriptet från samma mapp. Det verkar fungera! Tack så mycket!

Två saker som jag kom på:

  1. Jag skulle vilja radera alla filer som har samma namn i samband med att dupliceringen skapas. Så om det redan finns "test_20230107_2235.txt" och "test.txt" sparas i samma mapp, då ska "test_20230107_2235.txt" raderas tillsammans med "test.txt" i samband med att "test.txt" dupliceras och får ett nytt datum/tid. Så det ska alltid bara finnas en fil som har just det namnet (i detta fallet "test").

  2. Jag skulle vilja att scriptet bara körs om filändelsen är .txt.