46

Я запускаю приложение в командной строке или в оболочке Git , и я хотел бы получить вывод в Блокнот для более удобного просмотра и редактирования позже.

Я попробовал следующее, но я всегда получаю пустой экземпляр Блокнота:

diff file1.txt file2.txt | notepad

Я знаю, что могу перенаправить вывод в другой файл, а затем открыть файл в блокноте. Я хотел бы избежать дополнительного шага, потому что я просто привык использовать Vim или менее в системах, отличных от Windows.

10 ответов10

61

Из того, что я могу сказать, нет никакого способа напрямую передать в Блокнот.

Тем не менее, вы можете передать в clip а затем вставить в блокнот, например так:

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

Затем просто нажмите Ctrl+V в Блокноте.

31

Подумайте об использовании Vim или, в вашем случае, gVim, если вы предпочитаете графическое окружение.

Затем вы можете передать в него один дефис в качестве аргумента, который указывает Vim/gVim читать из стандартного ввода.

diff file1.txt file2.txt | gvim -
8

вот короткая программа для Windows, которая делает это правильно (без зазубрин буфера обмена). Он должен быть адаптирован к PowerShell, и я мог бы обновить этот ответ, если у меня будет время, но вы также можете просто использовать эту программу напрямую.

Ну, а как насчет PowerShell? Не нужно устанавливать другое приложение. К сожалению, вам нужно будет создать файл сценария где - нибудь в вашем PATH ...

Короткая версия, которую вы можете использовать

Если вы создадите командный файл (например, ShowInNotepad.bat) со следующим содержимым и поместите его в ваш путь к PATH :

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

Вы можете просто позвонить echo blah | ShowInNotepad из любой точки мира!

Обратите внимание , что это предположим , что вы используете последнюю иш версию Windows (Vista+) и не отключили PowerShell или неустановленной рамки .NET. Другими словами, установка Windows по умолчанию будет работать.


Длительное объяснение и альтернативы

Самый простой способ, который я могу придумать, - это автоматизировать действие вставки (Ctrl+V). Что, по крайней мере, еще один ответ уже делает, но тот, который использует AHK - вам, возможно, повезет больше, если заставить PowerShell работать в закрытой корпоративной среде.

Давайте продолжим со сценарием, да?

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

Это довольно просто, поэтому я не буду объяснять сценарий больше, чем комментарии.

использование

Чтобы использовать его, вам просто нужно поместить скрипт в файл .ps1 (например, ShowInNotepad.ps1), поместить его где-нибудь в вашей PATH и затем вызвать powershell ShowInNotepad.ps1 после размещения текста, который вы хотите отобразить в буфере обмена.

Пример:

echo blah | clip && powershell ShowInNotepad.ps1

К сожалению, выполнение сценариев PowerShell иногда может быть затруднено (политики выполнения и все). Поэтому я сжал этот скрипт до одной строки, которую вы можете вызвать непосредственно из командной строки или даже поместить в командный файл:

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.bat) со следующим содержимым и поместите его в ваш путь к PATH :

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

Вы можете просто позвонить echo blah | ShowInNotepad из любой точки мира!

5

Как насчет использования AutoHotkey?

Сохраните следующее как stdin.ahk и поместите его в каталог 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 = 
        }
}

Тогда командная строка:

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

Передает вывод команды в Блокнот, пока окно открыто и называется Untitled - Notepad . Если окно не активно, оно будет активно буферизоваться в фоновом режиме, пока окно не станет активным. Вы даже можете перейти к другой программе, и она снова продолжит буферизацию.

Это, кажется, умирает, когда программа, выводящая на наш стандартный ввод, умирает, хотя ...

(Для информации, код stdin() был бесстыдно полдюйма отсюда)

4

Это вполне возможно; Я только что попробовал это. Я предполагаю, что Блокнот по умолчанию настроен на открытие текстовых файлов:

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

Хорошо, вы технически создаете файл, но он не сохраняется.

Трубить больше - это тоже вариант.

1

Вот уродливый, но эффективный способ сделать это:

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

Только обязательно отправляйте только текстовые сообщения. Другие данные могут быть интерпретированы как управляющие символы (CTRL, ALT, DEL и т.д.).

0

Вот пара решений на основе VBScript, которые могут работать (хотя ... они полагаются на приложения, которые открываются вовремя):

pipe2key.vbs - открывает приложение, указанное в качестве первого аргумента, а затем отправляет StdIn как нажатия клавиш. Необходимо использовать с cscript.exe, так как wscript не обеспечивает доступ к StdIn. Вероятно, довольно медленно для длинных документов - но не будет загромождать буфер обмена

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

Пример использования: diff file1.txt file2.txt | cscript pipe2key.vbs notepad.exe

Или pasteinto.vbs. Автоматизирует операцию CTRL-V после запуска приложения (таким образом, используется команда «clip», как упоминалось в предыдущих ответах). Значительно быстрее и чище (на мой взгляд), чем pipe2key.vbs, но процесс перезапишет буфер обмена

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"

Пример использования: diff file1.txt file2.txt | clip && pasteinto notepad.exe

-1

Нечто подобное "может" работать.

О, ты не понимал, что это то, что ты будешь делать каждый раз вручную (по звукам этого). Возможно, вам удастся создать какой-то макрос или что-то, что будет делать это каждый раз, чтобы ускорить процесс. Не уверен в этом.

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

Это должно было бы закончить запись содержимого diff в файл file.txt, чтобы загрузить всю операцию diff, что я не уверен, будет ли это выполнено. В этом случае может быть способ сделать паузу между операциями канала.

-3

Мой язык не английский, так что извините за ошибки.

Я думаю, что вы не можете напрямую поместить вывод в открытый блокнот. Может быть, я ошибаюсь по этому поводу. Вы должны создать файл с выводом, чтобы работать с ним. Команда tee может передать вывод двум или может быть несколькими командами или файлами одновременно.

человек тройник

Не забудьте использовать >> вместо> при перенаправлении вывода в файл. > Перезапишет файл, >> добавит вывод после того, что уже есть в этом файле.

-4

Вы не можете, Блокнот слишком ограничен для этого! А еще лучше ... установить Cygwin и обойти все это "отсутствие функций" Windows. Затем вы можете использовать команду, которую вы уже знаете.

AFAIK, очень немногие программы для Windows поддерживают конвейерную обработку, еще хуже для программ с графическим интерфейсом.

Вы можете попытаться открыть запросы функций в одной из программ "хвоста Windows", чтобы добавить это.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .