如何将控制台输出直接通过管道传输到记事本?

Der*_*ler 48 windows notepad command-line

我正在命令提示符或Git shell上运行一个应用程序,我想将输出输入记事本,以便以后更容易地查看和编辑。

我尝试了以下操作,但我总是得到一个空的记事本实例:

diff file1.txt file2.txt | notepad
Run Code Online (Sandbox Code Playgroud)

我知道我可以将输出重定向到另一个文件,然后在记事本中打开该文件。我想避免额外的步骤,因为我只是习惯于在非 Windows 系统上使用Vim或更少的管道。

Der*_*ler 65

据我所知,无法直接通过管道输入记事本。

但是,您可以通过管道输入clip然后粘贴到记事本中,如下所示:

 diff file1.txt file2.txt | clip && notepad
Run Code Online (Sandbox Code Playgroud)

然后只需在记事本中按Ctrl+ V

  • @Konerak 是的,这会起作用,这正是我试图避免的(如问题中所述);) (4认同)
  • 如果您将输出重定向到 file3.txt,然后是 `&& notepad file3.txt`,它会起作用吗? (3认同)

小智 32

如果您更喜欢图形环境,请考虑使用Vim,或者在您的情况下使用 gVim 。

然后,您可以使用单个连字符作为参数通过管道输入它,它指示 Vim/gVim 从标准输入中读取。

diff file1.txt file2.txt | gvim -
Run Code Online (Sandbox Code Playgroud)

  • 也可以在 vim 中执行此操作:`:%!diff file1.txt file2.txt` (3认同)

Bob*_*Bob 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');
Run Code Online (Sandbox Code Playgroud)

然后你可以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');
Run Code Online (Sandbox Code Playgroud)

它非常简单,所以我不会比注释已经解释的更多。

用法

要使用它,您只需要将脚本放在一个.ps1文件中(例如ShowInNotepad.ps1),将它放在您的某个位置PATH,然后powershell ShowInNotepad.ps1在将要显示的文本放入剪贴板后调用。

例子:

echo blah | clip && powershell ShowInNotepad.ps1
Run Code Online (Sandbox Code Playgroud)

不幸的是,执行 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');
Run Code Online (Sandbox Code Playgroud)

如果您创建一个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');
Run Code Online (Sandbox Code Playgroud)

然后你可以echo blah | ShowInNotepad从任何地方打电话!


Mok*_*bai 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 = 
        }
}
Run Code Online (Sandbox Code Playgroud)

然后命令行:

ping -t www.google.com | AutoHotkeyA32.exe stdin.ahk
Run Code Online (Sandbox Code Playgroud)

只要窗口是打开的并且标题为Untitled - Notepad. 如果窗口未处于活动状态,那么它将在后台愉快地缓冲,直到窗口处于活动状态。您甚至可以转到另一个程序,它会再次进行缓冲。

当输出到我们的标准输入的程序死亡时,这似乎就消失了......

(有关信息,stdin() 代码从这里无耻地半英寸)

  • @Gusdor 整个互联网充满了非版本控制的代码片段。我们甚至可以为这篇文章提供 [修订历史](http://superuser.com/posts/772453/revisions)。我也不明白商业许可与这个问题有什么关系?*很多*人都在使用AHK,他们可能会发现这个答案很有用。 (7认同)