Bagaimana melakukan apa yang dilakukan head, tail, more, less, sed di Powershell? [Tutup]

109

Pada jendela, menggunakan Powershell, apa perintah setara dengan linux ini head, tail, more, lessdan sed?

Yue Zhang
sumber
File log terlalu besar, sekitar beberapa MByte. Terlalu sulit untuk dilihat dengan notepad.exe.
Yue Zhang
Jika Anda menggunakan notepadsebagai basis Anda, saya sarankan untuk mencari editor teks alternatif, ada banyak alternatif (gratis dan berbayar). Semua lebih unggul dari notepad (meskipun itu tidak terlalu menantang).
Richard
kemungkinan duplikat PowerShell vs. Unix Shells
manojlds
Saya menangani file besar dan saya menggunakan / menginstal Vim yang terbukti jauh lebih cepat daripada alat lain yang pernah saya gunakan.
sfanjoy

Jawaban:

174

Get-Content(alias :) gcadalah opsi biasa Anda untuk membaca file teks. Anda kemudian dapat memfilter lebih lanjut:

gc log.txt | select -first 10 # head
gc -TotalCount 10 log.txt     # also head
gc log.txt | select -last 10  # tail
gc -Tail 10 log.txt           # also tail (since PSv3), also much faster than above option
gc log.txt | more             # or less if you have it installed
gc log.txt | %{ $_ -replace '\d+', '($0)' }         # sed

Ini berfungsi cukup baik untuk file kecil, yang lebih besar (lebih dari beberapa MiB) mungkin agak lambat.

The PowerShell Komunitas Extensions mencakup beberapa cmdlets untuk hal-hal berkas khusus (misalnya Get-FileTail).

Joey
sumber
3
Astaga, ini memaksimalkan CPU saya untuk melakukan -last 2pada CSV 1GB. Minuman panas: ☕
mlissner
9
@mlissner: Jika Anda menggunakan PowerShell v3, Anda dapat menggunakannya Get-Content -Tail 2. Itu pasti lebih cepat.
Joey
gc log.txt | %{ $_ -replace '\d+', '($0)' } # sedyang sebenarnya bukan sepenuhnya alat sed karena tidak mengembalikan konten. Itu membutuhkan Set-Content.
Artyom
3
@Neil, -Lastlambat karena alasan yang sama awkakan menjadi lambat untuk tugas yang sama: Ini harus menggunakan streaming sepenuhnya terlebih dahulu. Itulah mengapa Get-Content -Tailada. Dan tidak ada headkarena tidak sesuai dengan konvensi penamaan, dan tujuannya sudah dilayani oleh Select-Item.
Joey
3
@neil @joey Mereka memiliki alias untuk -head. Lihat jawaban saya stackoverflow.com/a/41626586/1081043
wisbucky
52

Berikut cara bawaan untuk melakukan headdan tail. Jangan gunakan pipa karena jika Anda memiliki file besar, itu akan sangat lambat. Menggunakan opsi bawaan ini akan sangat cepat bahkan untuk file besar.

gc log.txt -head 10 
gc log.txt -tail 10
gc log.txt -tail 10 -wait # equivalent to tail -f
bijak
sumber
tapi komentar Joey sepertinya menunjukkan kebalikannya! bagaimana saya tahu siapa yang harus dipercaya atau metode (bawaan) mana yang paling efisien?
NH.
2
@NH Jawaban saya sesuai dengan komentar Joey. Komentarnya mengatakan "-Terakhir lambat ... Itulah mengapa Get-Content -Tail ada." | select -lastmenggunakan pipa. Saya menggunakan -tailtanpa pipa. Tetapi jika Anda menemukan dua jawaban yang saling bertentangan, Anda mungkin bisa mempercayai orang dengan reputasi yang jauh lebih tinggi. Selain itu, Anda cukup mencoba dua metode pada file besar. Ini akan terlihat sangat jelas pada file besar.
wisbucky
Mengerti. Maaf, saya pasti bingung saat pertama kali membaca postingan.
NH.
8

more.exeada di Windows, port lessmudah ditemukan (dan PowerShell Community Extensions , PSCX, termasuk satu).

PowerShell tidak benar-benar menyediakan alternatif apa pun untuk program terpisah, tetapi untuk data terstruktur Out-Griddapat membantu.

Headdan Tailkeduanya dapat diemulasikan dengan Select-Objectmenggunakan parameter -Firstdan -Lastmasing-masing.

Sedsemua fungsi tersedia tetapi dengan struktur yang agak berbeda. Opsi pemfilteran tersedia di Where-Object(atau melalui Foreach-Objectdan beberapa status untuk rentang). Lainnya, transformasi, operasi dapat dilakukan dengan Select-Objectdan Foreach-Object.

Namun saat PowerShell melewati objek (.NET) - dengan semua struktur ketikannya, mis. tanggal tetap merupakan DateTimecontoh - bukan hanya string, yang harus diurai oleh setiap perintah, banyak dari seddan program serupa lainnya yang berlebihan.

Richard
sumber
Cemerlang. gc tampaknya tidak mendukung masukan pipa. ketika saya ingin memfilter output perintah, saya menggunakan "... exe ... | select-object -first 20 | select-object
-last
2

"-TotalCount" dalam contoh ini merespons persis seperti "-head". Anda harus menggunakan -TotalCount atau -head untuk menjalankan perintah seperti itu. Tetapi -TotalCount menyesatkan - ini tidak berfungsi SEBENARNYA memberi Anda hitungan APA PUN ...

gc -TotalCount 25 C:\scripts\logs\robocopy_report.txt

Script di atas, diuji di PS 5.1 adalah respon yang SAMA seperti di bawah ini ...

gc -head 25 C:\scripts\logs\robocopy_report.txt

Jadi gunakan saja '-head 25 "!

Patrick Burwell
sumber
Hai @Patrick, selamat datang di Stack Overflow! Terima kasih telah mencoba menjawab pertanyaan ini, dapatkah Anda memberikan penjelasan yang lebih detail? Tidak jelas apakah Anda mencoba menawarkan solusi atau hanya menambahkan beberapa komentar tentang masalah tersebut.
Rocío García Luque
Itu adalah komentar dan juga membuat frustrasi. '-TotalCount "tidak melakukan apa pun" -Head "belum melakukannya. Jadi, apakah ada yang TAHU cara mendapatkan TotalCount?
Patrick Burwell
Baca lagi ... saya menambahkan ke jawaban dan menjelaskan apa yang berhasil ...
Patrick Burwell
1

Jika Anda perlu menanyakan file log besar (atau kecil) pada Windows, alat terbaik yang saya temukan adalah Log Parser 2.2 gratis dari Microsoft . Anda dapat memanggilnya dari PowerShell jika Anda mau dan itu akan melakukan semua pekerjaan berat untuk Anda, dan juga sangat cepat.

Apa yang Akan Keren
sumber
terima kasih, lingkungan saya adalah Win2k8R2 yang tidak ada dalam persyaratan Sistem Log Parser2.2
Yue Zhang
0

Saya mendapat beberapa solusi yang lebih baik:

gc log.txt -ReadCount 5 | %{$_;throw "pipeline end!"} # head
gc log.txt | %{$num=0;}{$num++;"$num $_"}             # cat -n
gc log.txt | %{$num=0;}{$num++; if($num -gt 2 -and $num -lt 7){"$num $_"}} # sed
Yue Zhang
sumber
-1
$Push_Pop = $ErrorActionPreference #Suppresses errors
$ErrorActionPreference = SilentlyContinue #Suppresses errors
#Script
    #gc .\output\*.csv -ReadCount 5 | %{$_;throw "pipeline end!"} # head
    #gc .\output\*.csv | %{$num=0;}{$num++;"$num $_"}             # cat -n
    gc .\output\*.csv | %{$num=0;}{$num++; if($num -gt 2 -and $num -lt 7){"$num $_"}} # sed
#End Script 
$ErrorActionPreference = $Push_Pop #Suppresses errors

Anda tidak mendapatkan semua kesalahan dengan kode pushpop BTW, kode Anda hanya bekerja dengan opsi "sed". Sisanya mengabaikan apa pun kecuali gc dan jalur.

Patrick Burwell
sumber