Come posso inviare l'output della console direttamente al Blocco note?


47

Sto eseguendo un'applicazione dal prompt dei comandi o una shell Git e vorrei ottenere l'output in Blocco note, per una revisione e una modifica più facili in seguito.

Ho provato quanto segue, ma ottengo sempre un'istanza vuota di Blocco note:

diff file1.txt file2.txt | notepad

Sono consapevole di poter reindirizzare l'output su un altro file e quindi aprire il file in Blocco note. Vorrei evitare il passaggio aggiuntivo, perché sono solo abituato a eseguire il piping su Vim o meno su sistemi non Windows.


2
Ovviamente, puoi eseguire il pipe anche moresu Windows.
Gabe,

1
Perché non eseguire il pipe su file e semplicemente eseguire la shell il nuovo percorso del file: lasciare che il sistema operativo gestisca l'applicazione di presentazione. Ha deve essere blocco note?
Gusdor,

@Gusdor La domanda è principalmente di evitare di creare un file (temporaneo).
Der Hochstapler,

1
La funzionalità di Blocco note è così limitata che a malapena puoi farci qualsiasi cosa. Dato che hai familiarità vim, perché non installarlo?
Siyuan Ren,

@CR Potrei farlo sui miei computer, ma lavoro regolarmente su computer che non possiedo. Quindi è utile sapere quali opzioni ci sono senza installare software di terze parti.
Der Hochstapler,

Risposte:


63

Da quello che posso dire, non c'è modo di reindirizzare direttamente nel Blocco note.

Tuttavia, puoi reindirizzare clipe quindi incollare nel blocco note, in questo modo:

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

Quindi premi Ctrl+ Vnel Blocco note.


3
Funzionerebbe se reindirizzassi l'output su file3.txt e quindi && notepad file3.txt?
Konerak,

4
@Konerak Sì, avrebbe funzionato ed è esattamente quello che stavo cercando di evitare (come spiegato nella domanda);)
Der Hochstapler,

32

Prendi in considerazione l'utilizzo di Vim o, nel tuo caso, gVim se preferisci un ambiente grafico.

È quindi possibile reindirizzarlo con un singolo trattino come argomento, che indica a Vim / gVim di leggere dall'input standard.

diff file1.txt file2.txt | gvim -

1
installalo, il Blocco note è davvero limitato, non puoi usarlo per questo. puoi persino averlo nelle app portatili
higuita

3
Puoi anche farlo da dentro Vim::%!diff file1.txt file2.txt
SlightlyCuban,

@TankorSmash Anch'io, ma non è questo il punto della domanda;) Per ulteriori discussioni pro e contro su vim (o qualsiasi altro argomento), trovami su Super User Chat , i thread dei commenti non sono un ottimo modo per avere una conversazione :(
Der Hochstapler,

1
@OliverSalzburg Stavo cercando di suggerire che gvim è disponibile su Windows, poiché ho capito che il tuo commento significa che non lo era. Mi sbagliavo.
TankorSmash,

-è spesso usato per significare "letto da stdin", quindi questo non è strettamente limitato a vim. Altri editor usano -i(es kate.).
Bakuriu,

8

ecco un breve programma per Windows che lo fa correttamente (senza ostruire gli appunti). Dovrebbe essere adattabile a PowerShell e potrei aggiornare questa risposta se ho tempo, ma puoi anche usare direttamente quel programma.

Bene, che ne dici di PowerShell? Non è necessario installare un'altra applicazione. Purtroppo, si sarà necessario creare un file di script da qualche parte nel vostro PATH...

Versione corta che puoi usare

Se si crea un file batch (ad es. ShowInNotepad.bat) Con i seguenti contenuti e lo si inserisce da PATHqualche parte:

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

puoi quindi chiamare echo blah | ShowInNotepadda qualsiasi luogo!

Si noti che questo non presumere che si sta usando una versione recente-ish di Windows (Vista +) e non hanno disabilitato PowerShell o disinstallato il framework .NET. In altre parole, funzionerà un'installazione di Windows predefinita.


Spiegazione lunga e alternative

Il modo più semplice a cui riesco a pensare è automatizzare l'azione incolla ( Ctrl+ V). Quale almeno un'altra risposta sta già facendo, ma quella utilizza AHK: potresti avere più fortuna a far funzionare PowerShell in un ambiente aziendale bloccato.

Andiamo avanti con la sceneggiatura, sì?

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

È piuttosto semplice, quindi non mi preoccuperò di spiegare la sceneggiatura più di quanto già facciano i commenti.

uso

Per usarlo, devi solo posizionare lo script in un .ps1file (ad esempio ShowInNotepad.ps1), posizionarlo da qualche parte nel tuo PATHe quindi chiamare powershell ShowInNotepad.ps1dopo aver inserito il testo che desideri visualizzare negli Appunti.

Esempio:

echo blah | clip && powershell ShowInNotepad.ps1

Sfortunatamente, l'esecuzione degli script di PowerShell può talvolta essere difficile (criteri di esecuzione e tutto il resto). Pertanto, ho condensato questo script in un one-liner che puoi chiamare direttamente dal Prompt dei comandi o persino inserirlo in un 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');

Se si crea un file batch (ad es. ShowInNotepad.bat) Con i seguenti contenuti e lo si inserisce da PATHqualche parte:

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

puoi quindi chiamare echo blah | ShowInNotepadda qualsiasi luogo!


Onestamente, se hai intenzione di scrivere uno script PS, creerei un file con un nome Guid nella cartella dei file temporanei e lo eliminerei quando ho finito. L'automazione della pasta sembra troppo fragile (come se perdessi la messa a fuoco nel momento sbagliato o qualcosa del genere)?
Casey,

@emodendroket Sfortunatamente, quando stai provando a forzare l'input del flusso in un programma che non lo supporta in modo nativo, nulla è veramente pulito. La creazione di un file temporaneo ha i suoi (minori) svantaggi: in realtà non si ottiene un "nuovo file", quindi i Savecomportamenti di uscita e quelli modificati sono diversi. A parte sostituire il Blocco note stesso o iniettare direttamente il testo nel suo controllo di modifica, non ci sono molte altre opzioni. Naturalmente, questo metodo ha lo svantaggio di ostruire il contenuto degli appunti (anche se si suppone che siano comunque effimeri). Non credo che perdere la concentrazione sia un grosso problema; è un ...
Bob,

... condizioni di gara estremamente improbabili (tra i ShowWindowtasti di invio e di invio). E questo metodo richiede un po 'più di installazione (creazione del file di script) da usare, sì.
Bob,

5

Che ne dici di usare AutoHotkey ?

Salvare quanto segue stdin.ahke inserirlo nella directory AutoHotkey:

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

Quindi la riga di comando:

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

Instrada l'output del comando nel Blocco note, a condizione che la finestra sia aperta e titolata Untitled - Notepad. Nel caso in cui la finestra non sia attiva, verrà tamponata allegramente in background fino a quando la finestra non sarà attiva. Puoi anche andare via a un altro programma e continuerà a bufferizzare ancora una volta.

Questo sembra morire quando muore il programma in uscita al nostro input standard ...

(Per informazione, il codice stdin () era spudoratamente mezzo pollice da qui )


...Wow. Se hai intenzione di andare fino a quel punto, potresti anche scrivere un intero programma compilato! Probabilmente anche più efficiente: P Voto positivo per lo sforzo.
Bob,

A mio avviso, ho paura. Ingegnerizzazione eccessiva in senso classico. Chi è la versione che controlla questo script? Autohotkey ha bisogno di una licenza per applicazioni commerciali? Chi lo controlla?
Gusdor,

7
@Gusdor L'intera Internet è piena di frammenti di codice non controllati dalla versione. Abbiamo anche il vantaggio di avere una cronologia delle revisioni per questo post. Inoltre non vedo come le licenze commerciali abbiano qualcosa a che fare con questa domanda? AHK è utilizzato da molte persone e potrebbe trovare utile questa risposta.
slhck,

@slhck Stavo semplicemente osservando le insidie ​​di questa soluzione, non la sua validità.
Gusdor,

@slhck: i contenuti di questo sito sono coperti da Creative Commons.
Brian,

4

Questo è totalmente possibile; L'ho appena provato. Presumo che Blocco note sia impostato per aprire i file txt per impostazione predefinita:

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

OK, tecnicamente stai creando un file, ma non viene salvato.

Anche il piping in more è un'opzione.


4
Fai attenzione: se ne hai già uno, output.txtquesto lo ostruirà. Marginalmente più sicuro sarebbe usare %temp%/somerandomstring.txt.
Bob,

È più sicuro salvare un file di output nella directory temporanea - dai un'occhiata a questa risposta.
Lu55,

1

Ecco un modo brutto, ma efficace per ottenere questo risultato:

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

Assicurati di inviare solo output di testo. Altri dati verranno potenzialmente interpretati come caratteri di controllo (CTRL, ALT, CANC, ecc.).


0

Ecco un paio di soluzioni basate su VBScript che potrebbero funzionare (anche se .. si basano un po 'sulle app che si aprono in tempo):

pipe2key.vbs: apre l'applicazione specificata come primo argomento, quindi invia StdIn come sequenze di tasti. Deve essere utilizzato con cscript.exe poiché wscript non fornisce l'accesso StdIn. Probabilmente abbastanza lento per documenti lunghi, ma non ostruirà gli appunti

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

Esempio di utilizzo: diff file1.txt file2.txt | cscript pipe2key.vbs notepad.exe

Oppure, pasteinto.vbs. Automatizza l'operazione CTRL-V dopo aver avviato un'app (utilizza quindi il comando 'clip' come indicato nelle risposte precedenti). Molto più veloce e più pulito (secondo me) di pipe2key.vbs, ma il processo sovrascriverà gli appunti

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"

Esempio di utilizzo: diff file1.txt file2.txt | clip && pasteinto notepad.exe


-1

Qualcosa del genere "potrebbe" funzionare.

Aw, non ti sei reso conto che questo è qualcosa che faresti manualmente ogni volta (dai suoni di esso). Potresti essere in grado di creare una sorta di macro o qualcosa per farlo ogni volta per accelerare il processo. Non sono sicuro su quello.

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

Dovrebbe finire di scrivere i contenuti diff su file.txt per poter caricare l'intera operazione diff che non sono sicuro che lo farà. In tal caso potrebbe esserci un modo per mettere in pausa in qualche modo tra l'operazione di tubazione.


5
L'obiettivo è non creare un file temporaneo e sono abbastanza sicuro che ci sia qualcosa di sbagliato nella tua sintassi lì;)
Der Hochstapler,

"per una più facile revisione e modifica in seguito" Ho pensato che fosse quello che volevi? E come Rev1.0 ha sottolineato e modificato, funziona. Questo è per dos, tuttavia, non sono sicuro che Cygwin avrebbe gli stessi risultati.
Codezilla,

3
Immagino perché un & sarebbe adeguato dal momento che in realtà nulla deve essere "convogliato" tra quelle chiamate.
Rev1.0

3
@ Rev1.0 Corretto. &, &&E ||sono operatori ai comandi concatenare. Tutti e 3 si comportano diversamente nel modo in cui procedono se un comando genera un valore di ritorno diverso da 0. |è completamente diverso in quanto viene utilizzato per reindirizzare l' output da un programma a un altro. Il risultato potrebbe essere quello che volevi, ma l'utilizzo di uno degli operatori di concatenamento rende più chiaro l'intento, poiché in questo esempio non è richiesta alcuna tubazione effettiva. Per ulteriori riferimenti: microsoft.com/resources/documentation/windows/xp/all/proddocs/…
Der Hochstapler,

1
@Codezilla Penso che l'idea nel mio post sia abbastanza simile alla tua ma è una sintassi del prompt dei comandi valida.
Casey,

-3

La mia lingua non è l'inglese, quindi mi dispiace per gli errori.

Penso che non sia possibile inserire direttamente l'output nel Blocco note aperto. Forse mi sbaglio. Devi creare un file con l'output in esso per lavorare su di esso. Il comando tee può reindirizzare l'output a due o potrebbe essere più comandi o file contemporaneamente.

tee uomo

Non dimenticare di usare >> invece> quando si reindirizza l'output nel file. > Sovrascriverà il file, >> aggiungerà l'output dopo tutto ciò che è già in quel file.


1
teedi solito non è disponibile su Windows e, anche se lo fosse, non aiuterebbe con questo problema.
Der Hochstapler,

-4

Non puoi, Notepad è troppo limitato per questo! Meglio ancora ... installa Cygwin e risolvi tutta questa "mancanza di funzionalità" di Windows. È quindi possibile utilizzare il comando che già conosci.

AFAIK, pochissimi programmi Windows supportano il pipelining, peggio ancora per i programmi GUI.

Puoi provare ad aprire le richieste di funzionalità a uno dei programmi "windows tail" per aggiungerlo.


2
Uso già cygwin. Questo è davvero un problema specifico dell'interazione con Blocco note.
Der Hochstapler,


1
@emodendroket alcune volte le persone usano lo strumento sbagliato per un lavoro ... e per quasi tutti i casi, il blocco note è lo strumento sbagliato, è così semplice e limitato :)
higuita

1
@higuita Sono un devoto utente di Emacs ma a volte Notepad è lo strumento migliore per quello che voglio fare.
Casey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.