PowerShell: Lưu trữ Toàn bộ Nội dung Tệp Văn bản trong Biến


118

Tôi muốn sử dụng PowerShell để lưu trữ toàn bộ nội dung của tệp văn bản (bao gồm cả dòng trống ở cuối có thể tồn tại hoặc không) trong một biến. Tôi cũng muốn biết tổng số dòng trong tệp văn bản. Cách hiệu quả nhất để làm điều này là gì?

Câu trả lời:


122

Để lấy toàn bộ nội dung của tệp:

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

Số dòng:

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

hoặc là

(gc .\test.ps1).length

Phân loại hackish để bao gồm dòng trống ở cuối:

[io.file]::ReadAllText(".\desktop\git-python\test.ps1").split("`n").count

1
Cảm ơn! $content = [IO.File]::ReadAllText(".\test.txt")dường như làm điều tương tự như $content = (gc ".\test.txt" | out-string). Vì giây thứ hai ngắn hơn, đó là điều tôi thích. Thật không may, cả hai phương pháp bạn đã cung cấp để tính tổng số dòng đều không tính đến các dòng trống ở cuối. Bất kỳ ý tưởng nào khác?
Nick

@Nick In .Net (và windows), bất kỳ dòng nào có \r\nsẽ được tính.
manojlds

Tôi đã thực hiện một số thử nghiệm và đưa ra điều tương tự như câu trả lời cập nhật của bạn, nhưng tôi sẽ không đạt được điều đó nếu không có sự giúp đỡ của bạn, vì vậy cảm ơn bạn rất nhiều!
Nick

Có cách nào để kết hợp điều này một cách minh bạch với Invoke-WebRequest?
Kareem

189

Một lưu ý nhỏ, trong PowerShell 3.0, bạn có thể sử dụng Get-Contentlệnh ghép ngắn với công tắc Raw mới:

$text = Get-Content .\file.txt -Raw 

3
Đây là câu trả lời được chấp nhận. Nhân tiện, tôi khá chắc chắn rằng Get-Content đã hoạt động ngay cả trong các phiên bản trước đó.
MatteoSp

10
@MatteoSp Get-Contentđã có, nhưng phải đến 3.0 mới có -Raw. Nếu không có điều đó, nó sẽ được lưu trữ dưới dạng một mảng các dòng.
jpmc26

Đây hoàn toàn nên là câu trả lời được chấp nhận. Việc tài liệu nói rằng -Rawtham số không được thực hiện bởi bất kỳ thứ gì gốc.
Richard Szalay

Cảm ơn, đây là một sự giúp đỡ tuyệt vời vừa rồi.
DAhrens

24

Powershell 2.0:

(xem giải thích chi tiết tại đây)

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

IO.File.ReadAllTextkhông hoạt động với tôi với một đường dẫn tương đối, nó tìm kiếm tệp trong %USERPROFILE%\$filePaththay vì thư mục hiện tại (ít nhất là khi chạy từ Powershell ISE):

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

Powershell 3+:

$text = Get-Content $filePath -Raw

Để sử dụng thân con đường, giải quyết nó đầu tiên ví dụ như:[IO.File]::ReadAllText((Resolve-Path $filePath))
mvanle

13

Một cách tiếp cận khác để đọc một tệp mà tôi tình cờ thích được gọi là ký hiệu biến hoặc cú pháp biến và chỉ liên quan đến việc bao gồm một tệp tin trong dấu ngoặc nhọn đứng trước dấu đô la, để hiểu:

$content = ${C:file.txt}

Ký hiệu này có thể được sử dụng như một giá trị L hoặc một giá trị R ; do đó, bạn có thể dễ dàng ghi vào một tệp có nội dung như sau:

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

Một cách sử dụng hữu ích khác là bạn có thể sửa đổi tệp tại chỗ mà không cần tệp tạm thời và không có biểu thức phụ, ví dụ:

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

Tôi đã bị cuốn hút bởi ký hiệu này ban đầu vì rất khó để tìm hiểu bất cứ điều gì về nó! Ngay cả thông số kỹ thuật PowerShell 2.0 đề cập đến nó chỉ một lần hiển thị chỉ một dòng sử dụng nó - nhưng không có giải thích hoặc chi tiết sử dụng nào cả. Sau đó, tôi đã tìm thấy mục blog này về các biến PowerShell cung cấp một số thông tin chi tiết tốt.

Một lưu ý cuối cùng khi sử dụng điều này: bạn phải sử dụng ký hiệu ổ đĩa, tức là ${drive:filespec}như tôi đã làm trong tất cả các ví dụ ở trên. Không có ổ đĩa (ví dụ ${file.txt}) nó không hoạt động. Không có hạn chế nào đối với tệp tin trên ổ đĩa đó: nó có thể là tuyệt đối hoặc tương đối.


Tôi chưa bao giờ làm việc này trừ khi tôi đặt dấu gạch chéo ngược sau tên ổ đĩa.
Charles Anderson,

@CharlesAnderson: Không rõ bạn đang đề cập đến ví dụ nào, hoặc có lẽ là tất cả chúng ... tuy nhiên, tôi chỉ xác nhận rằng cả 3 đều hoạt động với một đường dẫn tương đối (tức là không có dấu gạch chéo ngược) trong PowerShell V3. Hơn nữa, tại thời điểm trả lời của tôi, tôi đang sử dụng V2, vì vậy có lẽ có điều gì đó khác gây ra sự cố trong môi trường của bạn.
Michael Sorens

Ý tôi là các ví dụ như $ {C: file.txt}, mà tôi phải viết là $ {C: \ file.txt}. Vâng, tôi cho rằng đó là điều gì đó về môi trường của tôi, nhưng tôi không biết là gì.
Charles Anderson

Khi sử dụng dưới dạng giá trị L, nó sử dụng mã hóa mặc định của hệ thống. Tôi đã cố gắng đặt $ OutputEncoding không có hiệu lực. Khi sử dụng dưới dạng giá trị R, nó tạo ra một mảng chuỗi [].
robert 4

Có vẻ như bạn chỉ có thể sử dụng tên đường dẫn theo nghĩa đen; bạn không thể sử dụng một biến hoặc một cái gì đó như biểu thức Tham gia đường dẫn bên trong này. Điều này thật khó chịu, bởi vì khi chuyển qua ConvertTo-Json, có một thế giới khác biệt so với Get-Content (và kết quả $ {...} là điều tôi mong đợi. Tôi không chắc liệu điều này có giống nhau không dưới dạng Get-Content | Out-String mặc dù
Cameron Kerr

2

Get-Content lấy dữ liệu và đưa nó vào một mảng, từng dòng. Giả sử không có yêu cầu đặc biệt nào khác so với bạn đã liệt kê, bạn có thể lưu nội dung của mình vào một biến không?

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

Chỉ chạy $filesẽ trả về nội dung đầy đủ. Sau đó, bạn chỉ có thể làm $file.Count(vì mảng đã có sẵn một phương thức đếm) để lấy tổng số dòng.

Hi vọng điêu nay co ich! Tôi không phải là thuật sĩ viết kịch bản, nhưng điều này có vẻ dễ dàng hơn với tôi so với rất nhiều thứ ở trên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.