PowerShell: Przechowuj całą zawartość pliku tekstowego w zmiennej

118

Chciałbym użyć programu PowerShell do przechowywania całej zawartości pliku tekstowego (w tym końcowego pustego wiersza, który może istnieć lub nie) w zmiennej. Chciałbym również poznać całkowitą liczbę wierszy w pliku tekstowym. Jaki jest najskuteczniejszy sposób na zrobienie tego?

Nacięcie
źródło

Odpowiedzi:

122

Aby pobrać całą zawartość pliku:

$content = [IO.File]::ReadAllText(".\test.txt")

Liczba linii:

([IO.File]::ReadAllLines(".\test.txt")).length

lub

(gc .\test.ps1).length

Coś w rodzaju hakera polegającego na dołączeniu końcowej pustej linii:

[io.file]::ReadAllText(".\desktop\git-python\test.ps1").split("`n").count
manojlds
źródło
1
Dzięki! $content = [IO.File]::ReadAllText(".\test.txt")wydaje się robić to samo co $content = (gc ".\test.txt" | out-string). Ponieważ drugi z nich jest krótszy, to właśnie wolę. Niestety żadna z podanych przez Ciebie metod obliczania całkowitej liczby wierszy nie uwzględnia końcowych pustych wierszy. Jakieś inne pomysły?
Nick
@Nick W .Net (i Windows), każda linia z \r\nzostanie policzona.
manojlds
Trochę eksperymentowałem i wymyśliłem to samo, co twoja zaktualizowana odpowiedź, ale nie dotarłbym tam bez twojej pomocy, więc bardzo dziękuję!
Nick
Czy jest sposób, aby w przejrzysty sposób to połączyć Invoke-WebRequest?
Kareem
189

Na marginesie, w PowerShell 3.0 możesz użyć polecenia Get-Contentcmdlet z nowym przełącznikiem Raw:

$text = Get-Content .\file.txt -Raw 
Shay Levy
źródło
3
To powinna być akceptowana odpowiedź. Nawiasem mówiąc, jestem prawie pewien, że Get-Content działało nawet we wcześniejszych wersjach.
MatteoSp
10
@MatteoSp Get-Contenttak, ale dopiero w wersji 3.0 -Raw. Bez tego jest przechowywany jako tablica linii.
jpmc26
To powinna być absolutnie akceptowana odpowiedź. Nie pomaga, że dokumentacja mówi, że -Rawparametr nie jest implementowany przez nic natywnego.
Richard Szalay
Dzięki, to była teraz wielka pomoc.
DAhrens
24

Powershell 2.0:

(zobacz szczegółowe wyjaśnienie tutaj)

$text = Get-Content $filePath | Out-String

IO.File.ReadAllTextNie działa na mnie ze ścieżki względnej, szuka pliku w %USERPROFILE%\$filePathzamiast bieżącego katalogu (gdy uruchomiony z PowerShell ISE co najmniej):

$text = [IO.File]::ReadAllText($filePath)

Powershell 3+:

$text = Get-Content $filePath -Raw
Kapé
źródło
Aby użyć ścieżek krewnych, najpierw rozwiąż to, np .:[IO.File]::ReadAllText((Resolve-Path $filePath))
mvanle
13

Jeszcze jedno podejście do czytania pliku, który przypadkiem mi się podoba, jest różnie określane jako notacja zmiennej lub składnia zmiennej i polega po prostu na umieszczeniu specyfikacji pliku w nawiasach klamrowych poprzedzonych znakiem dolara, a mianowicie:

$content = ${C:file.txt}

Ten zapis może być użyty jako wartość L lub R ; w ten sposób możesz równie łatwo pisać do pliku za pomocą czegoś takiego:

 ${D:\path\to\file.txt} = $content

Innym przydatnym zastosowaniem jest to, że można modyfikować plik na miejscu bez pliku tymczasowego i bez wyrażeń podrzędnych, na przykład:

${C:file.txt} = ${C:file.txt} | select -skip 1

Początkowo zafascynował mnie ten zapis, ponieważ bardzo trudno było się o nim dowiedzieć! Nawet specyfikacja PowerShell 2.0 wspomina o tym tylko raz, pokazując tylko jedną linię, która go używa - ale bez żadnego wyjaśnienia ani szczegółów użycia. Później znalazłem ten wpis na blogu na temat zmiennych PowerShell, który daje dobre spostrzeżenia.

Ostatnia uwaga na temat używania tego: musisz użyć oznaczenia dysku, tj ${drive:filespec}. Tak jak zrobiłem we wszystkich powyższych przykładach. Bez napędu (np. ${file.txt}) Nie działa. Brak ograniczeń co do specyfikacji pliku na tym dysku: może być bezwzględna lub względna.

Michael Sorens
źródło
Nigdy nie udało mi się to zadziałać, chyba że wstawię ukośnik odwrotny po nazwie dysku.
Charles Anderson
@CharlesAnderson: Nie jest jasne, do którego z trzech przykładów się odnosisz, a może do wszystkich… niemniej jednak właśnie potwierdziłem, że wszystkie trzy działają ze ścieżką względną (tj. Bez odwrotnego ukośnika) w PowerShell V3. Co więcej, w momencie mojej odpowiedzi używałem V2, więc być może jest coś innego powodującego problem w twoim środowisku.
Michael Sorens
Miałem na myśli przykłady takie jak $ {C: file.txt}, które muszę zapisać jako $ {C: \ file.txt}. Tak, przypuszczam, że dotyczy to mojego środowiska, ale nie mam pojęcia, co.
Charles Anderson
Gdy jest używany jako wartość L, używa domyślnego kodowania systemu. Próbowałem ustawić $ OutputEncoding bez żadnego efektu. Używając jako wartości R, tworzy tablicę string [].
robert4
Wygląda na to, że możesz użyć tylko dosłownej nazwy ścieżki; nie możesz użyć w tym zmiennej ani czegoś takiego jak wyrażenie Join-Path. Co jest denerwujące, ponieważ po przesłaniu przez ConvertTo-Json jest ogromna różnica w porównaniu z Get-Content (a wynik $ {...} jest tym, na co liczyłem. Nie jestem pewien, czy to jest to samo jako Get-Content | Out-String choć
Cameron Kerr
2

Get-Content pobiera dane i zrzuca je do tablicy, wiersz po wierszu. Zakładając, że nie ma innych specjalnych wymagań niż wymienione, możesz po prostu zapisać zawartość w zmiennej?

$file = Get-Content c:\file\whatever.txt

Uruchomienie po prostu $filezwróci pełną zawartość. Następnie możesz po prostu zrobić $file.Count(ponieważ tablice mają już wbudowaną metodę zliczania), aby uzyskać całkowitą liczbę linii.

Mam nadzieję że to pomoże! Nie jestem kreatorem skryptów, ale wydawało mi się to łatwiejsze niż wiele rzeczy powyżej.

Jerry T.
źródło