Sprawdź, czy plik istnieje czy nie w programie Windows PowerShell?

121

Mam ten skrypt, który porównuje pliki w dwóch obszarach dysku i kopiuje najnowszy plik na ten ze starszą datą modyfikacji.

$filestowatch=get-content C:\H\files-to-watch.txt

$adminFiles=dir C:\H\admin\admin -recurse | ? { $fn=$_.FullName; ($filestowatch | % {$fn.contains($_)}) -contains $True}

$userFiles=dir C:\H\user\user -recurse | ? { $fn=$_.FullName; ($filestowatch | % {$fn.contains($_)}) -contains $True}

foreach($userfile in $userFiles)
{

      $exactadminfile= $adminfiles | ? {$_.Name -eq $userfile.Name} |Select -First 1
      $filetext1=[System.IO.File]::ReadAllText($exactadminfile.FullName)
      $filetext2=[System.IO.File]::ReadAllText($userfile.FullName)
      $equal = $filetext1 -ceq $filetext2 # case sensitive comparison

      if ($equal) { 
        Write-Host "Checking == : " $userfile.FullName 
        continue; 
      } 

      if($exactadminfile.LastWriteTime -gt $userfile.LastWriteTime)
      {
         Write-Host "Checking != : " $userfile.FullName " >> user"
         Copy-Item -Path $exactadminfile.FullName -Destination $userfile.FullName -Force
       }
       else
       {
          Write-Host "Checking != : " $userfile.FullName " >> admin"
          Copy-Item -Path $userfile.FullName -Destination $exactadminfile.FullName -Force
       }
}

Oto format plików do obejrzenia.txt

content\less\_light.less
content\less\_mixins.less
content\less\_variables.less
content\font-awesome\variables.less
content\font-awesome\mixins.less
content\font-awesome\path.less
content\font-awesome\core.less

Chciałbym to zmodyfikować, aby uniknąć tego, jeśli plik nie istnieje w obu obszarach i wyświetla komunikat ostrzegawczy. Czy ktoś może mi powiedzieć, jak mogę sprawdzić, czy plik istnieje, używając PowerShell?

Samantha JT Star
źródło

Odpowiedzi:

209

Aby zaoferować alternatywę dla Test-Pathcmdletu (ponieważ nikt o tym nie wspomniał):

[System.IO.File]::Exists($path)

Robi (prawie) to samo co

Test-Path $path -PathType Leaf

z wyjątkiem braku obsługi znaków wieloznacznych

Mathias R. Jessen
źródło
1
@orad Tak, widziałem, wysłałem odpowiedź z zanegowanym wywołaniem Exists (), ale nie spotkałem się z tą samą pozytywną odpowiedzią ;-)
Mathias R. Jessen
5
Użycie [System.IO.File]::Existstakże inaczej rozwiązuje ścieżki względne i Test-Pathmoże być używane z ścieżkami innymi niż pliki (np. Lokalizacje w rejestrze). Użyj Test-Path.
jpmc26
2
Metody @Jamie Native .NET zwykle rozwiązują ścieżki względem katalogu roboczego procesu, niekoniecznie bieżącej ścieżki FileSystem w PowerShell. Możesz to zrobić[System.IO.File]::($(Join-Path $PWD $path))
Mathias R. Jessen
1
A jeśli nie zgadłeś, dotyczy to [System.IO.Directory]::Exists($path)folderów. Oba obsługują ścieżki UNC w moim systemie, ale aby robić ukryte udostępnienia, pamiętaj, aby uciec $na ścieżce jako „$”
Chris Rudd
74

Użyj ścieżki testowej :

if (!(Test-Path $exactadminfile) -and !(Test-Path $userfile)) {
  Write-Warning "$userFile absent from both locations"
}

Umieszczenie powyższego kodu w ForEachpętli powinno zrobić to, co chcesz

arco444
źródło
23

Chcesz użyć Test-Path:

Test-Path <path to file> -PathType Leaf
GodEater
źródło
7

Standardowym sposobem sprawdzenia, czy plik istnieje, jest Test-Pathużycie polecenia cmdlet.

Test-Path -path $filename
Mike Shepard
źródło
6

Możesz użyć Test-Pathpolecenia cmd-let. Więc coś w stylu ...

if(!(Test-Path [oldLocation]) -and !(Test-Path [newLocation]))
{
    Write-Host "$file doesn't exist in both locations."
}
Speerian
źródło
0
cls

$exactadminfile = "C:\temp\files\admin" #First folder to check the file

$userfile = "C:\temp\files\user" #Second folder to check the file

$filenames=Get-Content "C:\temp\files\files-to-watch.txt" #Reading the names of the files to test the existance in one of the above locations

foreach ($filename in $filenames) {
  if (!(Test-Path $exactadminfile\$filename) -and !(Test-Path $userfile\$filename)) { #if the file is not there in either of the folder
    Write-Warning "$filename absent from both locations"
  } else {
    Write-Host " $filename  File is there in one or both Locations" #if file exists there at both locations or at least in one location
  }
}
MA Charlotte
źródło
-5

Test-Path może dać dziwną odpowiedź. Np. „Test-Path c: \ temp \ -PathType leaf” daje wartość false, ale „Test-Path c: \ temp * -PathType leaf” daje true. Smutny :(

Zoltan Hernyak
źródło