Konsol çıkışını doğrudan Not Defteri'ne nasıl aktarabilirim?


47

Komut isteminde veya Git kabuğu üzerinde bir uygulama çalıştırıyorum ve daha sonra daha kolay gözden geçirmek ve düzenlemek için çıktıyı Not Defteri'ne almak istiyorum.

Aşağıdakileri denedim, ancak her zaman boş bir Not Defteri örneği alıyorum:

diff file1.txt file2.txt | notepad

Çıktıyı başka bir dosyaya yönlendirebilir ve ardından dosyayı Not Defteri'nde açabileceğimin farkındayım. Ekstra adımdan kaçınmak istiyorum, çünkü sadece Windows olmayan sistemlerde Vim veya daha azına boru alıyorum .


2
Tabii ki, moreWindows'a da yönlendirebilirsiniz.
Gabe

1
Neden dosyaya aktarmıyor ve basitçe kabuk yeni dosya yolunu çalıştırıyor - işletim sisteminin sunum uygulamasını yönetmesine izin verin. Not defteri olmak zorunda mı ?
Gusdor

@Gusdor Soru öncelikle (geçici) bir dosya oluşturmaktan kaçınmakla ilgilidir.
Der Hochstapler

1
Notepad'in işlevselliği o kadar sınırlıdır ki onunla bir şey yapamazsınız. Aşina olduğunuzdan vimneden sadece kurmuyorsunuz?
Siyuan Ren,

@ CR Bunu kendi bilgisayarlarımda yapabilirdim, ancak düzenli olarak sahip olmadığım bilgisayarlarda çalışıyorum. Bu nedenle, üçüncü taraf yazılımı yüklemeden hangi seçeneklerin olduğunu bilmek faydalı olacaktır.
Der Hochstapler

Yanıtlar:


63

Söyleyebileceğim kadarıyla, doğrudan Not Defteri'ne aktarmanın yolu yok.

Ancak, bunun gibi boru içine clipve sonra not defterine yapıştırabilirsiniz :

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

Sonra sadece Not Defteri'nde Ctrl+ tuşuna basın V.


3
Çıktıyı file3.txt dosyasına yönlendirirseniz işe yarar mıydı && notepad file3.txt?
Konerak

4
@Konerak Evet, bu işe yarar ve tam olarak kaçınmaya çalıştığım şey buydu (soruda açıklandığı gibi);)
Der Hochstapler

32

Kullanmayı düşünün Vim bir grafik ortamı tercih olursa veya durumda GVIM içinde.

Ardından Vim / gVim'e standart girişten okuma talimatı veren argüman olarak tek bir tire ile boru oluşturabilirsiniz.

diff file1.txt file2.txt | gvim -

1
yükle, Not Defteri gerçekten bunun için kullanamazsın sınırlıdır. taşınabilir uygulamalarda bile kullanabilirsiniz: portableapps.com/apps/development/gvim_portable
higuita

3
Bunu vim içinden de yapabilirsiniz::%!diff file1.txt file2.txt
SlightlyCuban

@TankorSmash Öyleyse ben, ama bu sorunun amacı değil;) Vim (veya başka bir konu) ile ilgili daha fazla profesyonel ve konuyla ilgili tartışmalar için, lütfen Süper Kullanıcı Sohbetinde beni bulun , yorum konuları bir sohbet etmenin harika bir yolu değil :(
Der Hochstapler

1
@OliverSalzburg Yorumunuzu anladığımdan beri anladığımdan, Windows'ta gvim'in kullanılabilir olduğunu önermeye çalışıyordum. Ben hatalıydım.
TankorSmash

-sık sık "stdin'den okumak" anlamına gelir, bu nedenle bu kesinlikle ile sınırlı değildir vim. Diğer editörler -i(örneğin kate) kullanır.
Bakuriu

8

İşte düzgün bir şekilde yapan kısa bir Windows programı . PowerShell'e uyarlanabilir olması gerekir ve zaman alırsam bu cevabı güncelleyebilirim, ancak doğrudan bu programı da kullanabilirsiniz.

Peki ya PowerShell? Başka bir uygulama kurmanıza gerek yok. Ne yazık ki, olacak Gözlerinde farklı bir komut dosyası bir yere oluşturmanız gerekir PATH...

Kullanabileceğiniz kısa versiyon

ShowInNotepad.batAşağıdaki içeriğe sahip bir toplu iş dosyası (örn. ) PATHOluşturup bir yere koyarsanız:

@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');

o zaman echo blah | ShowInNotepadher yerden arayabilirsiniz !

Bunun , Windows'un (Vista +) en son sürümlerini kullandığınızı ve PowerShell'i devre dışı bırakmadığınızı veya .NET çerçevesini kaldırmadığınızı varsaydığını unutmayın . Başka bir deyişle, varsayılan bir Windows yüklemesi çalışacaktır.


Uzun açıklama ve alternatifler

Aklıma gelen en kolay yol yapıştırma ( Ctrl+ V) eylemini otomatikleştirmektir . Hangi en az bir cevabın zaten cevapladığı, ancak AHK'yi kullanan kişi - PowerShell'i kilitli bir şirket ortamında çalışmak için daha iyi bir şansa sahip olabilir.

Senaryoyu yazalım, tamam mı?

#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');

Çok basit, bu yüzden komut dosyasını zaten yorumlardan daha fazla açıklamaya zahmet etmeyeceğim.

kullanım

Kullanmak için sadece betiği bir .ps1dosyaya (örn. ShowInNotepad.ps1) Yerleştirmeniz, bir yere yerleştirmeniz ve sonra panoda görüntülemek istediğiniz metni yerleştirdikten PATHsonra çağırmanız yeterlidir powershell ShowInNotepad.ps1.

Örnek:

echo blah | clip && powershell ShowInNotepad.ps1

Ne yazık ki, PowerShell scriptlerinin çalıştırılması bazen zor olabilir (çalıştırma politikaları ve diğerleri). Bu nedenle, bu komut dosyasını doğrudan Komut İsteminden arayabileceğiniz veya hatta bir toplu iş dosyasına yerleştirebileceğiniz tek bir çizgide yoğunlaştırdım:

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');

ShowInNotepad.batAşağıdaki içeriğe sahip bir toplu iş dosyası (örn. ) PATHOluşturup bir yere koyarsanız:

@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');

o zaman echo blah | ShowInNotepadher yerden arayabilirsiniz !


Dürüst olmak gerekirse, bir PS betiği yazacaksanız temp dosyası klasöründe Guid ismiyle bir dosya oluşturacağım ve bittiğinde onu sileceğim. Macunu otomatikleştirmek çok kırılgan görünüyor (ya yanlış zamanda veya başka bir şeyde odağını kaybederseniz)?
Casey,

@emodendroket Ne yazık ki, akış girdisini yerel olarak desteklemeyen bir programa zorlamak istediğinizde hiçbir şey gerçekten temiz değildir. Temp dosyası oluşturmanın kendine has sakıncaları vardır: aslında "yeni bir dosya" almazsınız, bu yüzden Saveve değiştirilen davranışlardan çıkış farklıdır. Not Defteri'nin kendisini değiştirmekten veya metni doğrudan düzenleme denetimine enjekte etmekten kısa, başka bir seçenek yoktur. Tabii ki, bu yöntem gizlilik panosu içeriğinin dezavantajına sahiptir (bunun yine de geçici olması gerekir). Odaklanmanın önemli bir sorun olduğunu düşünmüyorum; bu bir ...
Bob

... son derece muhtemel olmayan yarış durumu ( ShowWindowve arasında tuş vuruşlarını göndererek). Ve bu yöntem kullanmak için biraz daha kurulum (komut dosyası oluşturma) gerektirir, evet.
Bob

5

AutoHotkey'i kullanmaya ne dersiniz ?

Aşağıdakileri kaydedin ve stdin.ahkAutoHotkey dizininize yerleştirin:

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 = 
        }
}

Sonra komut satırı:

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

Komutun çıktısını, pencere açık ve başlıklı olduğu sürece Not Defteri'ne aktarır Untitled - Notepad. Pencerenin aktif olmaması durumunda, pencere aktif olana kadar arka planda neşeyle tamponlanır. Başka bir programa bile gidebilirsiniz ve bir kez daha tamponlama devam edecektir.

Bu, standart girdilerimize çıktıran program ölürken ölüyor gibi görünüyor ...

(Bilgi için, stdin () kodu utanmazca buradan yarı-inched idi )


...vay. Bu ölçüde gidecekseniz, derlenmiş bir program da yazabilirsiniz! Muhtemelen daha verimli olmak için: P Yine de çaba için olumlu olun.
Bob

Benden aşağı oy ver, korkarım. Klasik anlamda mühendislik. Bu betiği kim kontrol ediyor? Autohotkey ticari uygulamalar için bir lisansa ihtiyaç duyuyor mu? Bunu kim izler?
Gusdor

7
@Gusdor İnternetin tamamı, sürüm denetlenmeyen kod parçacıklarıyla doludur. Bu yazı için bir revizyon geçmişine sahip olmanın avantajına sahibiz . Ayrıca, ticari lisanslamanın bu soruyla ne alakası olduğunu da anlamıyorum? AHK birçok kişi tarafından kullanılır ve bu cevabı faydalı bulabilirler.
slhck

@slhck Ben sadece geçerliliğini değil, bu çözümün tuzaklar üzerinde duruyordum.
Gusdor

@slhck: Bu sitedeki içerik Creative Commons kapsamındadır.
Brian,

4

Bu tamamen mümkün; Sadece denedim. Notepad’in varsayılan olarak txt dosyalarını açacak şekilde ayarlandığını varsayıyorum:

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

Tamam, teknik olarak bir dosya oluşturuyorsunuz, ancak kaydedilmiyor.

Daha fazlasına pipetlemek de bir seçenektir.


4
Dikkatli olun - eğer zaten bir hakkınız varsa, output.txtbunu engelleyecektir. Marjinal olarak daha güvenli kullanmak olacaktır %temp%/somerandomstring.txt.
Bob

Bir çıktı dosyasını temp dizinine kaydetmek daha güvenlidir - bu cevaba bir göz atın .
Lu55,

1

İşte bunu başarmanın çirkin, ama etkili bir yolu:

$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)

Sadece metin çıktısı gönderdiğinizden emin olun. Diğer veriler potansiyel olarak kontrol karakterleri olarak yorumlanacaktır (CTRL, ALT, DEL, vs.).


0

İşte işe yarayabilecek birkaç VBScript tabanlı çözüm (her ne kadar .. zamanla açılan uygulamalara biraz güveniyorlarsa):

pipe2key.vbs - ilk argüman olarak belirtilen uygulamayı açar ve sonra StdIn'i tuş vuruşları olarak gönderir. Wscript StdIn erişimi sağlamadığından cscript.exe ile birlikte kullanılması gerekiyor. Muhtemelen uzun belgeler için oldukça yavaştır - fakat panoya zarar vermez

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

Örnek kullanım: diff file1.txt file2.txt | cscript pipe2key.vbs notepad.exe

Veya, pasteinto.vbs. Bir uygulamayı başlattıktan sonra CTRL-V işlemini otomatikleştirir (bu nedenle önceki cevaplarda belirtildiği gibi 'clip' komutunu kullanır). Pipe2key.vbs'den çok daha hızlı ve temiz (bence), ancak işlem panonun üzerine yazacak

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"

Örnek kullanım: diff file1.txt file2.txt | clip && pasteinto notepad.exe


-1

Bunun gibi bir şey işe yarayabilir.

Aa, ya bunun her seferinde manuel olarak yapabileceğin bir şey olduğunun farkında değildi (seslerinden). Süreci hızlandırmak için her zaman sizin için bir tür makro veya bunu yapmak için bir şeyler yapabilirsiniz. Ondan emin değilim.

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

Diff işleminin tamamını yükleyebilmesi için diff içeriğini file.txt dosyasına yazmayı bitirmek zorunda kalacaktı. Durum buysa, borunun çalışması arasında bir şekilde duraklamanın bir yolu olabilir.


5
Amaç geçici bir dosya oluşturmak değil ve sözdiziminizde yanlış bir şeyler olduğundan eminim;)
Der Hochstapler

"daha sonra daha kolay inceleme ve düzenleme için" İstediğin şeyin bu olduğunu düşündüm? Ve Rev1.0'ın işaret ettiği ve değiştirildiği gibi çalışır. Bu dos içindir, ancak cygwin'in aynı sonuçları elde edip etmeyeceğinden emin değilim.
Codezilla

3
Sanırım bir & yeterli olacaktır çünkü aslında hiçbir şey bu çağrılar arasında "aktarılmalı" değildir.
Rev1.0

3
@ Rev1.0 Doğru. &, &&Ve ||bir araya zincir komutlarına operatörleri. Komut 0 olmayan bir dönüş değeri oluşturuyorsa, tüm 3, nasıl devam ettikleri konusunda farklı davranır. |bu için kullanıldığı gibi tamamen farklı bir boru başka bir programdan çıkış. Sonuç istediğin gibi olabilir, ancak zincirleme operatörlerinden birini kullanmak niyetini netleştirir, çünkü bu örnekte gerçek boru tesisatı istenmez. Ek başvuru için: microsoft.com/resources/documentation/windows/xp/all/proddocs/…
Der Hochstapler

1
@Codezilla Gönderimdeki fikrin sizinkiyle aynı olduğunu düşünüyorum ancak geçerli komut istemi sözdizimi var.
Casey,

-3

Dilim İngilizce değil, hatalar için üzgünüm.

Sanırım çıktıyı doğrudan Not Defteri'ne koyamazsınız. Belki bu konuda yanılmışım. Üzerinde çalışmak için çıktısını içeren bir dosya oluşturmanız gerekir. Komut tee çıkışı ikiye götürebilir veya aynı anda daha fazla komut veya dosya olabilir.

erkek tişört

Dosya yerine çıktıyı yeniden düştüğünde >> yerine> kullanmayı unutmayın. >, Dosyanın üzerine yazacaktır, >> çıktıda o dosyada ne varsa sonra ekleyecektir.


1
teeWindows'ta genellikle bulunmaz ve bu sorunu çözse bile bu sorunu çözmez.
Der Hochstapler

-4

Yapamazsın, Not Defteri bunun için çok sınırlı! Daha da iyisi ... Cygwin'i kurun ve Windows'un tüm bu "özellik eksikliğini" düzeltin. Daha sonra zaten bildiğiniz komutu kullanabilirsiniz.

AFAIK, çok az Windows programı boru hattını desteklemektedir, GUI programları için daha da kötüdür.

Bu özellik eklemek için "windows tail" programlarından birine özellik istekleri açmayı deneyebilirsiniz.


2
Ben zaten cygwin kullanıyorum. Bu gerçekten Not Defteri ile etkileşime özgü bir sorundur.
Der Hochstapler


1
@emodendroket bazen insanlar bir iş için yanlış aracı kullanırlar ... ve hemen hemen her durumda, not defteri yanlış bir araçtır, çok basit ve sınırlıdır :)
higuita

1
@higuita Ben sadık bir Emacs kullanıcısıyım ama bazen Not Defteri yapmak istediğim şey için daha iyi bir araçtır.
Casey,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.