Bagaimana saya bisa mem-pipe output konsol langsung ke Notepad?

47

Saya menjalankan aplikasi pada command prompt atau Git shell, dan saya ingin mendapatkan output ke Notepad, untuk ditinjau lebih mudah dan diedit nanti.

Saya mencoba yang berikut ini, tetapi saya selalu mendapatkan instance Notepad kosong:

diff file1.txt file2.txt | notepad

Saya sadar bahwa saya dapat mengarahkan output ke file lain dan kemudian buka file di Notepad. Saya ingin menghindari langkah ekstra, karena saya hanya terbiasa dengan Vim atau kurang pada sistem non-Windows.

Der Hochstapler
sumber
2
Tentu saja, Anda juga bisa menggunakan pipa untuk moreWindows.
Gabe
1
Mengapa tidak pipa ke file dan cukup jalankan path file baru - biarkan OS menangani aplikasi presentasi. Apakah itu harus menjadi notepad?
Gusdor
@ Goddor Pertanyaannya terutama tentang menghindari membuat file (sementara).
Der Hochstapler
1
Fungsionalitas Notepad sangat terbatas sehingga Anda hampir tidak dapat melakukan apa pun dengannya. Karena Anda terbiasa vim, mengapa tidak menginstalnya saja?
Siyuan Ren
@CR Saya bisa melakukannya di komputer saya sendiri, tetapi saya secara teratur bekerja di komputer yang bukan milik saya. Jadi, sangat membantu untuk mengetahui opsi mana yang ada tanpa menginstal perangkat lunak pihak ketiga.
Der Hochstapler

Jawaban:

63

Dari apa yang bisa saya katakan, tidak ada cara untuk langsung menyalurkan ke Notepad.

Namun, Anda dapat menyambungkan ke clipdan kemudian menempelkannya di notepad, seperti:

 diff file1.txt file2.txt | clip && notepad

Kemudian cukup tekan Ctrl+ Vdi Notepad.

Der Hochstapler
sumber
3
Apakah ini akan berhasil jika Anda mengarahkan output ke file3.txt, lalu && notepad file3.txt?
Konerak
4
@Konerak Ya, itu akan berhasil dan itulah yang saya coba hindari (seperti yang dijelaskan dalam pertanyaan);)
Der Hochstapler
32

Pertimbangkan untuk menggunakan Vim , atau dalam kasus Anda gVim jika Anda lebih suka lingkungan grafis.

Anda kemudian dapat memasukkan ke dalamnya dengan tanda hubung tunggal sebagai argumen, yang menginstruksikan Vim / gVim untuk membaca dari input standar.

diff file1.txt file2.txt | gvim -
Benjamin Goodacre
sumber
1
instal, Notepad sangat terbatas Anda tidak dapat menggunakannya untuk ini. Anda bahkan dapat memilikinya di aplikasi portabel
higuita
3
Dapat juga melakukan ini dari dalam vim::%!diff file1.txt file2.txt
SlightlyCuban
@TankorSmash Saya juga, tetapi bukan itu yang menjadi pertanyaan;) Untuk diskusi pro dan kontra lebih lanjut mengenai vim (atau topik lainnya), silakan temukan saya di Obrolan Pengguna Super , utas komentar bukanlah cara yang bagus untuk berkomunikasi. :(
Der Hochstapler
1
@ OliverSalzburg Saya mencoba untuk menyarankan bahwa gvim tersedia di Windows, karena saya mengerti komentar Anda berarti bahwa itu bukan. Saya salah.
TankorSmash
-sering digunakan untuk berarti "membaca dari stdin", jadi ini tidak terbatas vim. Editor lain menggunakan -i(misalnya kate).
Bakuriu
8

inilah program Windows singkat yang melakukannya dengan benar (tanpa merusak clipboard). Seharusnya bisa beradaptasi dengan PowerShell, dan saya mungkin memperbarui jawaban ini jika saya punya waktu, tetapi Anda juga bisa langsung menggunakan program itu.

Nah, bagaimana dengan PowerShell? Tidak perlu menginstal aplikasi lain. Sayangnya, Anda akan perlu untuk membuat suatu tempat file script di Anda PATH...

Versi singkat yang dapat Anda gunakan

Jika Anda membuat file batch (mis. ShowInNotepad.bat) Dengan konten berikut dan letakkan di PATHsuatu tempat Anda :

@echo off
clip
powershell -Command $process = Start-Process -PassThru notepad;$SW_SHOW = 5;$sig = '[DllImport("""user32.dll""")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);';Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32;[Win32.NativeMethods]::ShowWindow($process.Id, $SW_SHOW) ^| Out-Null;Add-Type -AssemblyName System.Windows.Forms;[System.Windows.Forms.SendKeys]::SendWait('^^V');

Anda kemudian dapat menelepon echo blah | ShowInNotepaddari mana saja!

Catatan bahwa ini tidak berasumsi bahwa Anda menggunakan versi terbaru-ish Windows (Vista +) dan memiliki tidak cacat PowerShell atau dihapus NET framework. Dengan kata lain, instalasi Windows default akan berfungsi.


Penjelasan panjang dan alternatif

Cara termudah yang dapat saya pikirkan adalah mengotomatiskan tindakan tempel ( Ctrl+ V). Yang setidaknya sudah dilakukan oleh satu jawaban lain, tetapi yang menggunakan AHK - Anda mungkin lebih beruntung mendapatkan PowerShell untuk bekerja di lingkungan perusahaan yang terkunci.

Ayo lanjutkan skripnya, ya?

#start notepad, get process object (to get pid later)
$process = Start-Process -PassThru notepad;

# activate Notepad window
# based on http://stackoverflow.com/a/4994020/1030702
# SW_SHOW activates and shows a window http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548%28v=vs.85%29.aspx
$SW_SHOW = 5;
$sig = '[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);';
Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32;
[Win32.NativeMethods]::ShowWindow($process.Id, $SW_SHOW) | Out-Null;

# send a "Ctrl+V" keystroke to the active window
# from http://stackoverflow.com/a/17851491/1030702
Add-Type -AssemblyName System.Windows.Forms;
[System.Windows.Forms.SendKeys]::SendWait('^V');

Ini cukup mudah, jadi saya tidak akan repot menjelaskan skrip lebih dari komentar yang sudah dilakukan.

Pemakaian

Untuk menggunakannya, Anda hanya perlu menempatkan skrip dalam .ps1file (misalnya ShowInNotepad.ps1), letakkan di suatu tempat di Anda PATHdan kemudian panggil powershell ShowInNotepad.ps1setelah menempatkan teks yang ingin Anda tampilkan di clipboard.

Contoh:

echo blah | clip && powershell ShowInNotepad.ps1

Sayangnya, menjalankan skrip PowerShell terkadang sulit (kebijakan eksekusi dan semua). Oleh karena itu, saya telah memadatkan skrip ini ke one-liner yang dapat Anda panggil langsung dari Command Prompt, atau bahkan ditempatkan ke dalam file batch:

powershell -Command $process = Start-Process -PassThru notepad;$SW_SHOW = 5;$sig = '[DllImport("""user32.dll""")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);';Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32;[Win32.NativeMethods]::ShowWindow($process.Id, $SW_SHOW) ^| Out-Null;Add-Type -AssemblyName System.Windows.Forms;[System.Windows.Forms.SendKeys]::SendWait('^^V');

Jika Anda membuat file batch (mis. ShowInNotepad.bat) Dengan konten berikut dan letakkan di PATHsuatu tempat Anda :

@echo off
clip
powershell -Command $process = Start-Process -PassThru notepad;$SW_SHOW = 5;$sig = '[DllImport("""user32.dll""")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);';Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32;[Win32.NativeMethods]::ShowWindow($process.Id, $SW_SHOW) ^| Out-Null;Add-Type -AssemblyName System.Windows.Forms;[System.Windows.Forms.SendKeys]::SendWait('^^V');

Anda kemudian dapat menelepon echo blah | ShowInNotepaddari mana saja!

Bob
sumber
Jujur jika Anda akan menulis skrip PS saya hanya akan membuat file dengan nama Guid di folder file temp dan menghapusnya ketika saya selesai. Mengotomatiskan pasta tampaknya terlalu rapuh (seperti bagaimana jika Anda kehilangan fokus pada waktu yang salah atau sesuatu)?
Casey
@emodendroket Sayangnya, ketika Anda mencoba untuk memaksa input stream ke program yang tidak mendukungnya, tidak ada yang benar-benar bersih. Membuat file temp memiliki sendiri (minor) kekurangannya: Anda tidak benar-benar mendapatkan "file baru", sehingga Savedan keluar pada perilaku dimodifikasi berbeda. Pendeknya mengganti Notepad itu sendiri atau langsung menyuntikkan teks ke dalam kontrol edit, tidak ada banyak pilihan lain. Tentu saja, metode ini memiliki kelemahan dari konten clipboard clobbering (meskipun itu seharusnya hanya sementara). Saya tidak berpikir kehilangan fokus adalah masalah utama; itu ...
Bob
... kondisi balapan yang sangat tidak mungkin (antara ShowWindowdan mengirim penekanan tombol). Dan metode ini memang membutuhkan sedikit lebih banyak pengaturan (membuat file skrip) untuk digunakan, ya.
Bob
5

Bagaimana dengan menggunakan AutoHotKey ?

Simpan yang berikut ini stdin.ahkdan letakkan di direktori AutoHotkey Anda:

StdIn(max_chars=0xfff)
{
    static hStdIn=-1
    ; The following is for vanilla compatibility
    ptrtype := (A_PtrSize = 8) ? "ptr" : "uint"

    if (hStdIn = -1)
    {
        hStdIn := DllCall("GetStdHandle", "UInt", -10,  ptrtype) ; -10=STD_INPUT_HANDLE
        if ErrorLevel
            return 0
    }

    max_chars := VarSetCapacity(text, max_chars*(!!A_IsUnicode+1), 0)

    ret := DllCall("ReadFile"
        ,  ptrtype, hStdIn        ; hFile
        ,  "Str", text          ; lpBuffer
        , "UInt", max_chars*(!!A_IsUnicode+1)     ; nNumberOfBytesToRead
        , "UInt*", bytesRead    ; lpNumberOfBytesRead
        ,  ptrtype, 0)            ; lpOverlapped

    return text
}

loop 
{
    sleep 100 ;wait for data
    Buffer:=StdIn()
    PipeText:=PipeText . Buffer
    IfWinActive Untitled - Notepad
        {
        SendInput {Raw}%PipeText%
        PipeText = 
        }
}

Maka baris perintah:

ping -t www.google.com | AutoHotkeyA32.exe stdin.ahk

Pipes output dari perintah ke Notepad, selama jendela terbuka dan berjudul Untitled - Notepad. Jika jendela tidak aktif maka akan dengan riang buffer di latar belakang sampai jendela aktif. Anda bahkan dapat pergi ke program lain dan itu akan melakukan buffering sekali lagi.

Ini tampaknya mati ketika program keluaran ke input standar kami mati meskipun ...

(Sebagai informasi, kode stdin () setengah inci tanpa malu-malu dari sini )

Mokubai
sumber
...Wow. Jika Anda akan pergi sejauh itu, mungkin juga menulis seluruh program yang dikompilasi! Mungkin lebih efisien juga: P Suara positif untuk usahanya.
Bob
Downvote dari saya, saya takut. Overengineering dalam arti klasik. Siapa versi yang mengendalikan skrip ini? Apakah autohotkey memerlukan lisensi untuk aplikasi komersial? Siapa yang memonitor itu?
Gusdor
7
@ Goddor Seluruh Internet penuh dengan cuplikan kode yang tidak dikontrol versi. Kami mendapat manfaat bahkan memiliki riwayat revisi untuk posting ini. Saya juga tidak melihat hubungan lisensi komersial dengan pertanyaan ini? AHK digunakan oleh banyak orang, dan mereka mungkin menemukan jawaban ini bermanfaat.
slhck
Sslhck Saya hanya berkomentar tentang perangkap solusi ini, bukan validitasnya.
Gusdor
@ slhck: Konten di situs ini dilindungi oleh Creative Commons.
Brian
4

Ini sangat mungkin; Saya baru saja mencobanya. Saya berasumsi Notepad diatur untuk membuka file txt secara default:

diff file1.txt file2.txt > output.txt && start output.txt && timeout /T 3 && del output.txt

OKE, Anda secara teknis membuat file, tetapi tidak disimpan.

Perpipaan ke lebih banyak juga merupakan pilihan.

Casey
sumber
4
Hati-hati - jika Anda sudah memiliki output.txtini akan mengalahkannya. Secara marginal lebih aman adalah menggunakan %temp%/somerandomstring.txt.
Bob
Lebih aman menyimpan file output di direktori temp - lihat jawaban ini .
Lu55
1

Inilah cara yang jelek, tetapi efektif untuk mencapai ini:

$OutputString = 'Hello World'
$WScript = New-Object -ComObject 'wscript.shell'
$WScript.Run('notepad.exe') | Out-Null
do 
    {
    Start-Sleep -Milliseconds 100
    }
until ($WScript.AppActivate('notepad'))
$WScript.SendKeys($OutputString)

Pastikan untuk hanya mengirim output teks. Data lain berpotensi ditafsirkan sebagai karakter kontrol (CTRL, ALT, DEL, dll.).

Sean
sumber
0

Berikut adalah beberapa solusi berbasis VBScript yang dapat bekerja (walaupun .. mereka sedikit bergantung pada pembukaan aplikasi tepat waktu):

pipe2key.vbs - membuka aplikasi yang ditentukan sebagai argumen pertama, dan kemudian mengirim StdIn sebagai penekanan tombol untuk itu. Perlu digunakan dengan cscript.exe karena wscript tidak menyediakan akses StdIn. Mungkin cukup lambat untuk dokumen yang panjang - tetapi tidak akan merusak clipboard

Set inPipe=wScript.StdIn
Set wShell=wScript.CreateObject("wscript.shell")
wShell.Run wScript.Arguments(0), 5 ' Execute specified app, foreground it's window
wScript.Sleep 500 ' Wait for app to load
KeysToEscape="{}[]()^+%"
KeysToDrop=vbLf
While Not inPipe.AtEndOfStream
    keyChar=inPipe.Read(1)
    If InStr(KeysToDrop, keyChar) = 0 Then
        If InStr(KeysToEscape, keyChar) > 0 Then
            wShell.SendKeys "{" & keyChar & "}"
        Else
            wShell.SendKeys keyChar
        End If
    End If
Wend

Contoh penggunaan: diff file1.txt file2.txt | cscript pipe2key.vbs notepad.exe

Atau, pasteinto.vbs. Mengotomatiskan operasi CTRL-V setelah meluncurkan aplikasi (dengan demikian menggunakan perintah 'klip' ​​seperti yang disebutkan dalam jawaban sebelumnya). Jauh lebih cepat dan lebih bersih (menurut saya) daripada pipe2key.vbs, tetapi prosesnya akan menimpa clipboard

Set wShell=wScript.CreateObject("wscript.shell")
wShell.Run wScript.Arguments(0), 5 ' Execute specified app, foreground it's window
wScript.Sleep 500 ' Wait for app to load
wShell.SendKeys "^v"

Contoh penggunaan: diff file1.txt file2.txt | clip && pasteinto notepad.exe

Jason Musgrove
sumber
-1

Sesuatu seperti ini "mungkin" bekerja.

Ah, kamu tidak menyadari ini adalah sesuatu yang akan kamu lakukan secara manual setiap kali (dari suara itu). Anda mungkin dapat membuat semacam makro atau sesuatu untuk Anda lakukan setiap kali untuk mempercepat proses. Tidak yakin dengan yang itu.

diff file1.txt file2.txt > file.txt | sleep 1 | notepad.exe file.txt | rm file.txt

Itu harus selesai menulis konten diff ke file.txt agar memuat seluruh operasi diff yang saya tidak yakin apakah itu akan dilakukan. Mungkin ada cara untuk menjeda entah bagaimana antara operasi pipa jika itu yang terjadi.

Codezilla
sumber
5
Tujuannya adalah untuk tidak membuat file sementara dan saya cukup yakin ada sesuatu yang salah dengan sintaks Anda di sana;)
Der Hochstapler
"untuk lebih mudah ditinjau dan diedit nanti," saya pikir itu yang Anda inginkan? Dan seperti yang ditunjukkan Rev1.0 dan diubah, itu berfungsi. Namun ini untuk dos, saya tidak yakin apakah cygwin akan memiliki hasil yang sama.
Codezilla
3
Saya kira karena & akan cukup karena sebenarnya tidak ada yang perlu "disalurkan" di antara panggilan-panggilan itu.
Rev1.0
3
@ Rev1.0 Benar. &, &&dan ||merupakan operator untuk menghubungkan perintah bersama. Semua 3 berperilaku berbeda dalam bagaimana mereka melanjutkan jika suatu perintah menghasilkan nilai balik non-0. |sama sekali berbeda karena digunakan untuk menyalurkan output dari satu program ke program lainnya. Hasilnya mungkin apa yang Anda inginkan, tetapi menggunakan salah satu operator chaining membuat maksud menjadi lebih jelas, karena tidak ada pemipaan yang sebenarnya diinginkan dalam contoh itu. Untuk referensi tambahan: microsoft.com/resources/documentation/windows/xp/all/proddocs/…
Der Hochstapler
1
@ Kodezilla Saya pikir ide dalam posting saya sangat mirip dengan Anda tetapi sintaks prompt perintah yang valid.
Casey
-3

Bahasa saya bukan bahasa Inggris, maaf untuk kesalahan.

Saya pikir Anda tidak bisa langsung memasukkan output ke Notepad terbuka. Mungkin saya salah tentang itu. Anda harus membuat file dengan output di dalamnya untuk dapat mengatasinya. Tee perintah dapat menyalurkan output ke dua atau mungkin lebih banyak perintah atau file dalam waktu yang bersamaan.

man tee

Jangan lupa untuk menggunakan >> sebaliknya> ketika Anda mengalihkan output ke dalam file. > Akan menimpa file, >> akan menambahkan output setelah apa pun yang sudah ada dalam file itu.

pengguna338167
sumber
1
teebiasanya tidak tersedia di Windows dan bahkan jika itu, itu tidak akan membantu dengan masalah ini.
Der Hochstapler
-4

Anda tidak bisa, Notepad terlalu terbatas untuk ini! Lebih baik lagi ... instal Cygwin dan selesaikan semua "kekurangan fitur" Windows ini. Anda kemudian dapat menggunakan perintah yang sudah Anda ketahui.

AFAIK, sangat sedikit program Windows yang mendukung pipelining, bahkan lebih buruk untuk program GUI.

Anda dapat mencoba membuka permintaan fitur ke salah satu program "windows tail" untuk menambahkannya.

higuita
sumber
2
Saya sudah menggunakan cygwin. Ini benar-benar masalah khusus untuk interaksi dengan Notepad.
Der Hochstapler
1
@emodendroket beberapa kali orang menggunakan alat yang salah untuk suatu pekerjaan ... dan untuk hampir semua kasus, notepad adalah alat yang salah, begitu sederhana dan terbatas :)
higuita
1
@ higuita Saya pengguna setia Emacs tapi terkadang Notepad adalah alat yang lebih baik untuk apa yang ingin saya lakukan.
Casey