Como posso canalizar a saída do console diretamente para o Bloco de Notas?

45

Estou executando um aplicativo no prompt de comando ou em um shell Git , e gostaria para obter a saída no Bloco de Notas, para revisão e edição mais fácil posteriormente.

Eu tentei o seguinte, mas sempre recebo uma instância vazia do Bloco de notas:

diff file1.txt file2.txt | notepad

Estou ciente de que posso redirecionar a saída para outro arquivo e, em seguida, abrir o arquivo no Bloco de Notas. Eu gostaria de evitar a etapa extra, porque estou acostumado a entrar em Vim ou menos em sistemas não Windows.

    
por Der Hochstapler 23.06.2014 / 11:19

10 respostas

58

Pelo que posso dizer, não há como canalizar diretamente no Bloco de Notas.

No entanto, você pode canalizar para clip e, em seguida, colar no bloco de notas, assim:

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

Em seguida, pressione Ctrl + V no Bloco de Notas.

    
por 23.06.2014 / 11:19
30

Considere o uso de Vim ou, no seu caso, gVim se você preferir um ambiente gráfico.

Você pode então canalizar para ele com um único hífen como um argumento, que instrui o Vim / gVim a ler a partir da entrada padrão.

diff file1.txt file2.txt | gvim -
    
por 23.06.2014 / 13:54
8

aqui 'é um pequeno programa do Windows que faz isso adequadamente (sem estrobiar a área de transferência). Ele deve ser adaptável ao PowerShell, e eu posso atualizar essa resposta se tiver tempo, mas você também pode usar esse programa diretamente.

Bem, e quanto ao PowerShell? Não há necessidade de instalar outro aplicativo. Infelizmente, você irá precisar criar um arquivo de script em algum lugar no seu PATH ...

Versão resumida que você pode usar

Se você criar um arquivo de lote (por exemplo, ShowInNotepad.bat ) com o seguinte conteúdo e colocá-lo no seu PATH em algum lugar:

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

você pode simplesmente chamar echo blah | ShowInNotepad de qualquer lugar!

Observe que isso faz presumir que você está usando uma versão recente do Windows (Vista +) e não desativou o PowerShell ou desinstalou o .NET framework. Em outras palavras, uma instalação padrão do Windows funcionará.

Explicação e alternativas longas

A maneira mais fácil de pensar é automatizar a ação colar ( Ctrl + V ). O que pelo menos uma outra resposta já está fazendo, mas aquela usa o AHK - você pode ter mais sorte em fazer com que o PowerShell funcione em um ambiente corporativo bloqueado.

Vamos continuar com o roteiro, sim?

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

É bastante simples, então não vou me incomodar em explicar o script mais do que os comentários já feitos.

Uso

Para usá-lo, basta colocar o script em um arquivo .ps1 (por exemplo, ShowInNotepad.ps1 ), colocá-lo em algum lugar no seu PATH e depois chamar powershell ShowInNotepad.ps1 depois de colocar o texto que você deseja exibir a área de transferência.

Exemplo:

echo blah | clip && powershell ShowInNotepad.ps1

Infelizmente, a execução de scripts do PowerShell pode, às vezes, ser difícil (políticas de execução e tudo). Portanto, eu tenho condensado este script para um one-liner que você pode chamar diretamente do Prompt de Comando, ou até mesmo colocar em um arquivo de lote:

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 você criar um arquivo de lote (por exemplo, ShowInNotepad.bat ) com o seguinte conteúdo e colocá-lo no seu PATH em algum lugar:

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

você pode simplesmente chamar echo blah | ShowInNotepad de qualquer lugar!

    
por 24.06.2014 / 13:40
5

Que tal usar o AutoHotkey ?

Salve o seguinte como stdin.ahk e coloque-o em seu diretório 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 = 
        }
}

Em seguida, a linha de comando:

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

Canaliza a saída do comando no Bloco de Notas, desde que a janela esteja aberta e seja denominada Untitled - Notepad . No caso de a janela não estar ativa, ela será ativada no fundo até que a janela esteja ativa. Você pode até mesmo ir embora para outro programa e ele continuará carregando novamente.

Isso parece morrer quando o programa que está saindo para nossa entrada padrão morrer ...

(Para informação, o código stdin () foi descaradamente meio eminente de aqui )

    
por 23.06.2014 / 19:10
4

Isso é totalmente possível; Eu apenas tentei. Estou assumindo que o Notepad está configurado para abrir arquivos txt por padrão:

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

OK, você está tecnicamente criando um arquivo, mas ele não é salvo.

Pipetar para mais também é uma opção.

    
por 23.06.2014 / 17:07
1

Aqui está uma maneira feia, mas eficaz de realizar isso:

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

Apenas certifique-se de enviar somente saída de texto. Outros dados potencialmente serão interpretados como caracteres de controle (CTRL, ALT, DEL, etc.).

    
por 01.12.2015 / 16:26
0

Veja algumas soluções baseadas em VBScript que podem funcionar (embora ... elas dependam um pouco de aplicativos abertos no prazo):

pipe2key.vbs - abre o aplicativo especificado como o primeiro argumento e, em seguida, envia o StdIn como pressionamento de teclas a ele. Precisa ser usado com cscript.exe como wscript não fornece acesso StdIn. Provavelmente muito lento para documentos longos - mas não vai estragar a área de transferência

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

Exemplo de uso: diff file1.txt file2.txt | cscript pipe2key.vbs notepad.exe

Ou, pasteinto.vbs. Automatiza a operação CTRL-V após o lançamento de um aplicativo (assim, usa o comando 'clip' como mencionado nas respostas anteriores). Consideravelmente mais rápido e mais limpo (na minha opinião) do que o pipe2key.vbs, mas o processo irá sobrescrever a área de transferência

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"

Exemplo de uso: diff file1.txt file2.txt | clip && pasteinto notepad.exe

    
por 24.06.2014 / 15:38
-1

Algo como isso "pode" funcionar.

Ah, você não percebeu que isso é algo que você faria manualmente a cada vez (pelos sons). Você pode fazer algum tipo de macro ou algo para fazer isso a cada vez para acelerar o processo. Não tenho certeza sobre isso.

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

Ele teria que terminar de escrever o conteúdo do diff no arquivo.txt para que ele carregasse a totalidade da operação do diff, o que eu não tenho certeza se ele fará. Pode haver uma maneira de pausar de alguma forma entre a operação do pipe, se for o caso.

    
por 23.06.2014 / 11:44
-3

Meu idioma não é inglês, desculpe por erros.

Acho que você não pode colocar diretamente a saída no bloco de notas aberto. Pode ser que eu esteja errado sobre isso. Você tem que criar um arquivo com a saída nele para trabalhar nele. O comando tee pode canalizar a saída para dois ou pode ser mais comandos ou arquivos ao mesmo tempo.

homem tee

Não se esqueça de usar > > em vez disso > quando você redura a saída no arquivo. O > sobrescreverá o arquivo, > > irá adicionar a saída após o que já está nesse arquivo.

    
por 24.06.2014 / 12:55
-4

Você não pode, o Bloco de Notas é muito limitado para isso! Melhor ainda ... instale o Cygwin e corrija toda essa "falta de recursos" do Windows. Você pode então usar o comando que você já conhece.

AFAIK, pouquíssimo pipelining de suporte a programas do Windows, pior ainda para programas GUI.

Você pode tentar abrir solicitações de recursos para um dos programas "windows tail" para adicioná-lo.

    
por 23.06.2014 / 16:14