【问题标题】:Can a macro in Notepad++ contain keystrokes?Notepad++ 中的宏可以包含击键吗?
【发布时间】:2016-06-21 21:53:32
【问题描述】:

如果我尝试在文本文件中创建一列并使用在文本文件的特定区域中找到的相同值填充该列,我可以使用正则表达式进行查找/替换以成功执行此操作。由于该列是最正确的,我找到\r 并替换为,VALUE,\r,其中VALUE 是从以前的副本(CTRL-C)命令粘贴的.问题是我不能让它在其他文件上作为宏工作,因为它记录了 CTRL-V 的值而不是击键命令 CTRL-V。宏有没有办法模拟 CTRL-V 而不是填充特定值?

添加信息: 文件中的每一行都需要粘贴的值。原因是因为每一行都包含一个产品编号和一个数量。通过能够粘贴在其中一个标题中找到的值,我可以将这些行链接到由粘贴的值表示的顺序。因此,一个表将包含订单号、日期等,而另一个表将包含订单的详细信息,即项目。

这是一个示例文件:

商品名称、商品编号、数量 STORE #578 PO 0076875422 04-01-2014,已发货
蓝鱼,98799,3
红鱼,48573,10
黄色蜗牛,94582,2
绿蜥蜴-中号,32451,12
黑狼蛛,29879,909

在 notepad++ 中运行脚本后,该文件将如下所示:
商品名称、商品编号、数量 STORE #578 PO 0076875422 04-01-2014、已发货、订单号 蓝鱼,98799,3,,0076875422
红鱼,48573,10,,0076875422
黄色蜗牛,94582,2,,0076875422
绿蜥蜴-中号,32451,12,,0076875422
黑狼蛛,29879,909,,0076875422

包含 QTY 的标题包含其他数据:商店数量、订单数量和订单日期。订单号始终以“PO”开头,并且始终为 10 位数字。宏需要能够在每个文件中找到它,然后将其添加到每一行的末尾,但它需要在前面加上逗号以允许 SHIPPED 列中的空值。当然,您还会注意到标题行中添加了一个名为 ORDER_NUMBER 的标题。

我遇到困难的地方是能够将订单号的值粘贴到当前宏中每行 b/c 的末尾,它只能粘贴录制时粘贴的值,而不是当前正在处理的文件中的实际采购订单编号。所以我想如果我可以在告诉宏在标题行中找到采购订单号并将其复制到剪贴板之后以某种方式记录 CTRL-V 击键,那么它就可以工作了。

【问题讨论】:

  • 复制和粘贴快捷方式在查找/替换对话框之外在宏中工作得很好。然而,它们似乎在对话框中不起作用——这可能是由于与给出的其他命令相比,对话框是如何记录的,但很难确定。我在Notepad++ Wiki 中找到了这一行,这就是我产生这个想法的原因:“Notepad++ 处理查找和替换记录自身的动作,因为它们会带来同样的困难。” 我目前正在寻找想办法做到这一点,但这可能是不可能的。
  • 嗨,肯德拉。如果您发现任何东西,很高兴收到回复。有人告诉我,python 脚本可以完成我想要完成的工作,但是 Notepadd ++ 无法像我希望的那样存储击键。
  • 我还没有找到自己做的方法。我曾希望插件可能会有所帮助,但我尝试过的都没有。我认为您最好的选择是使用脚本。也许未来的更新会做到这一点,但看起来这目前还不太可能。 (我还研究过手动编辑已保存的宏,但我认为我的系统出了点问题,导致它无法正确保存。如果我 确实 设法做到这一点并让它工作,我'将发布有关如何操作的答案。)
  • @chano 我想我可以提供一个可以帮助你的 nppexec 脚本。您会考虑使用 nppexec(通过插件管理器提供的 notepad++ 插件,您可以为 nppexec 脚本分配键盘快捷键)?如果是,请添加更多信息,例如您想将,VALUE 附加到文件中的每一行还是仅附加到某个子集(例如带有VALUE 的行)?最好将一些示例输入行添加到所需的输出行中。
  • 谢谢,Lars,是的,肯定会使用 nppexec 脚本。我会在帖子中添加一些信息。

标签: regex macros notepad++


【解决方案1】:

这是承诺的 NppExec 脚本。将其保存为 脚本名称,然后您可以将其添加到带有菜单 项目名称 的 NppExec 菜单(在 Plugins -> NppExec -> Advanced Options 中关联 script nameitem name),重新启动 notepad++ 后,您会在快捷方式映射器(插件选项卡下)的某处找到这个 item name 和您可以为其分配键盘快捷键。

npp_exec 脚本

// http://www.scintilla.org/ScintillaDoc.html
// http://docs.notepad-plus-plus.org/index.php/Moving_And_Selecting_Around

NPP_CONSOLE OFF

// 1. retrieve to PO:
  // 1.1 set the first line as target for the search
  SCI_SENDMSG SCI_DOCUMENTSTART
  SCI_SENDMSG SCI_LINEDOWN

  SCI_SENDMSG SCI_GETCURRENTPOS
  set Line1End ~ $(MSG_RESULT) -1

  // 1.2 do a RE search for the PO and retrieve the value for later reuse
  // set the range for the RE search to the first line
  SCI_SENDMSG SCI_SETTARGETSTART 0
  SCI_SENDMSG SCI_SETTARGETEND $(Line1End)

  SCI_SENDMSG SCI_SETSEARCHFLAGS SCFIND_REGEXP
  SCI_SENDMSG SCI_SEARCHINTARGET 11 "PO (\d{10})"
  set POPos=$(MSG_RESULT)

  if $(POPos) == -1 goto NOTFOUND

  // 1.3 get the PO Text:
  SCI_SENDMSG SCI_GETTAG 1 @""
  set POText=$(MSG_LPARAM)

  // 2 append ",ORDER_NUMBER" to first line
  SCI_SENDMSG SCI_DOCUMENTSTART
  SCI_SENDMSG SCI_LINEEND
  SCI_SENDMSG SCI_INSERTTEXT -1 @",ORDER_NUMBER"

  // 3 append POText to every other line
  SCI_SENDMSG SCI_LINEDOWN
  :REPEAT
    // 3.1 append ",POText" to line
    SCI_SENDMSG SCI_LINEEND
    SCI_SENDMSG SCI_INSERTTEXT -1 @",$(POText)"

    // 3.2 as long as we have not reached the last line: loop  
    SCI_SENDMSG SCI_LINEEND
    SCI_SENDMSG SCI_GETCURRENTPOS
    set pos1 = $(MSG_RESULT) 

    SCI_SENDMSG SCI_LINEDOWN
    SCI_SENDMSG SCI_GETCURRENTPOS
    set pos2 = $(MSG_RESULT) 

    // if the linedown doesnot give another pos, we have reached the end
    if $(pos1) == $(pos2) goto END
    // else loop
    if 1==1 goto REPEAT

  :NOTFOUND
    NPP_CONSOLE ON
    echo "There is no PO in the first line!"

  :END

它主要使用 NppExec 的SCI_SENDMSG 命令来远程控制编辑器。消息的文档位于第一行的链接中。但也有大量的试验和错误。

【讨论】:

  • @Chano 该解决方案不是很快:例如每秒只有几行。我担心这个问题不太适合记事本++。你有 sed 或 awk 可用吗?
  • 非常感谢拉斯和克里斯。我会尽快探索这个!
  • 拉尔斯,这确实有效!我只是在这里添加了一个逗号:SCI_SENDMSG SCI_INSERTTEXT -1 @",,$(POText)" 以便它可以为 SHIPPED 数据创建一个空白列。因为我最长的文件大约有 200 行,我认为速度可以忍受。 2个问题:如果文件以空行结尾,是否有一种简单的方法可以使它不在文件末尾创建行?此外,是否可以扩展相同的命令以对 QTY 标头中的其他字符串(例如商店编号)执行相同的操作?我没有 sed 或 awk。用户将使用 Windows 计算机。
【解决方案2】:

以下假设每个文件中只有一个采购订单号
并且应该在 Notepad++ 版本 6.4.3 及以后的版本中工作:

说明

1) Define a  macro `Save PO #` that  
    a) Finds and saves the PO # to the clipboard  
    b) Advances to the start of the following line  

2) Define a macro `Add PO #` that  
    a) Adds a comma to the end of a line then pastes the clipboard  
    b) Advances to the next line  

3) For each file  
    a) Run macro `Save PO #`  
    b) Run macro `Add PO #` to `end of file`  

方法

1) Start recording
Ctrl+Home
Find 查找内容:PO
Find Next Alt+F4
Right Edit Begin/End Select
Find 查找内容:<br>Find NextAlt+F4
LeftEditBegin/End SelectCtrl+CEnd@9876543444@
@9876EndOK
@9876 @姓名:Save PO #OK

2) Start recording End,Ctrl+VRight
Stop recording
Save current recorded macro姓名:Add PO #OK

3) 打开文件进行编辑
MacroSave PO #
Run a Macro Multiple Times
要运行的宏:Add PO #Run until end of fileRun

【讨论】:

  • 克里斯,它有效!在运行另一个之前先存储复制的字符串并关闭该宏的好主意。如果可以通过记住您的宏选择并关闭自身的键盘快捷键来完成多次运行宏到文件末尾,那就太棒了,但也许会在以后出现。
【解决方案3】:

由于 NPPExec 脚本很慢,这里还有一个纯 Notepad++ 的解决方案:

像这样进行正则表达式查找/替换:

  • 打开替换对话框
  • 查找内容: (PO (\d{10})[^\r\n]+\R(.*\2\R)*+)([^\r\n]+)(\R)
  • 替换为: \1\4,\2\5
  • 检查正则表达式
  • 点击替换或全部替换
  • 继续单击全部替换(或按住 ALT-A)直到不再进行替换(查找对话框的状态栏会告诉您)
  • 手动将,ORDER_NUMBER 附加到第一行

一个先决条件是最后一行的末尾有一个换行符,这意味着您必须在最后一行手动添加缺少的换行符,或者您需要手动插入 PO。

【讨论】:

  • 你好 Lars,非常感谢这个 Regex 建议。它仅在第一行找到查找和替换,但我会使用您的一些正则表达式并能够在其他地方应用它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多