如何在 Sublime Text 2 中过滤包含字符串的行的文件?

Dan*_*eck 80 text-editing sublime-text-2

我想过滤我在 Sublime Text 2 中编辑的文件,以便包含特定字符串的行,如果可能的话,包括正则表达式。

考虑以下文件:

foo bar
baz
qux
quuux baz
Run Code Online (Sandbox Code Playgroud)

过滤后ba,结果应该是:

foo bar
baz
quuux baz
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

Olo*_*son 89

还有一个穷人的行过滤算法(还是偷懒?):

  1. 选择感兴趣的字符串
  2. 在所有出现时点击Alt+F3进入多光标模式
  3. 点击Control+L选择整行(在每个光标行上)
  4. 将选择复制粘贴到另一个缓冲区

  • 这让我的生活变得更好。一切都将不再相同。 (5认同)
  • 对于 Mac 上的用户,请将步骤 2 替换为 ctl + cmd + G,将步骤 3 替换为 cmd + L - 效果很好! (5认同)
  • 不错的简单解决方案!我会将步骤 3 从 Ctrl-L 替换为 Home 、 Shift-End 因此,出现之间没有空行。 (3认同)
  • 这几乎是最简单的解决方案。太棒了! (2认同)

Dan*_*eck 88

Sublime Text 2 是一个带有Python API的可扩展编辑器。您可以创建新命令(称为Plugins)并使它们从 UI 中可用。

添加基本​​过滤 TextCommand 插件

在 Sublime Text 2 中,选择Tools » New Plugin并输入以下文本:

import sublime, sublime_plugin

def filter(v, e, needle):
    # get non-empty selections
    regions = [s for s in v.sel() if not s.empty()]
    
    # if there's no non-empty selection, filter the whole document
    if len(regions) == 0:
        regions = [ sublime.Region(0, v.size()) ]

    for region in reversed(regions):
        lines = v.split_by_newlines(region)

        for line in reversed(lines):
            if not needle in v.substr(line):
                v.erase(e, v.full_line(line))

class FilterCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        def done(needle):
            e = self.view.begin_edit()
            filter(self.view, e, needle)
            self.view.end_edit(e)

        cb = sublime.get_clipboard()
        sublime.active_window().show_input_panel("Filter file for lines containing: ", cb, done, None, None)
Run Code Online (Sandbox Code Playgroud)

保存filter.py~/Library/Application Support/Sublime Text 2/Packages/User

与用户界面集成

要将这个插件添加到编辑菜单,选择首选项…»浏览包并打开User文件夹。如果调用的文件Main.sublime-menu不存在,则创建它。向该文件添加或设置以下文本:

[
    {
        "id": "edit",
        "children":
        [
            {"id": "wrap"},
            { "command": "filter" }
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

这将在filter命令下方插入命令调用(本质上,filter转换FilterCommand().run(…)为插件调用和菜单标签的过滤器wrap。有关原因的更详细说明,请参见此处的步骤 11

要分配键盘快捷键,请Default (OSX).sublime-keymap在 OS X 或其他系统的等效文件上打开并编辑文件,然后输入以下内容:

[  
    {   
        "keys": ["ctrl+shift+f"], "command": "filter"
    }  
]  
Run Code Online (Sandbox Code Playgroud)

这将为该??F命令分配快捷方式。


要使命令显示在命令面板中,您需要Default.sublime-commandsUser文件夹中创建一个名为(或编辑现有文件)的文件。语法类似于您刚刚编辑的菜单文件:

[
    { "caption": "Filter Lines in File", "command": "filter" }
]
Run Code Online (Sandbox Code Playgroud)

多个条目(用大括号括起来)需要用逗号分隔。

 行为和 UI 集成屏幕截图

执行后,该命令将过滤作为选择一部分的所有行(整行,而不仅仅是选定部分),或者,如果不存在选择,则过滤整个缓冲区,用于输入到输入字段的子字符串(默认是 - 可能无用的多行 - 剪贴板)在命令被触发后。它可以很容易地扩展到例如支持正则表达式,或者只留下与某个表达式匹配的行。

菜单项

菜单中的命令

命令面板条目

命令面板中带有不同标签的命令

编辑

用户输入文本以过滤文件

执行命令后的结果

添加对正则表达式的支持

要添加对正则表达式的支持,请改用以下脚本和代码段:

filter.py

import sublime, sublime_plugin, re

def matches(needle, haystack, is_re):
    if is_re:
        return re.match(needle, haystack)
    else:
        return (needle in haystack)

def filter(v, e, needle, is_re = False):
    # get non-empty selections
    regions = [s for s in v.sel() if not s.empty()]
    
    # if there's no non-empty selection, filter the whole document
    if len(regions) == 0:
        regions = [ sublime.Region(0, v.size()) ]

    for region in reversed(regions):
        lines = v.split_by_newlines(region)

        for line in reversed(lines):

            if not matches(needle, v.substr(line), is_re):
                v.erase(e, v.full_line(line))

class FilterCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        def done(needle):
            e = self.view.begin_edit()
            filter(self.view, e, needle)
            self.view.end_edit(e)

        cb = sublime.get_clipboard()
        sublime.active_window().show_input_panel("Filter file for lines containing: ", cb, done, None, None)

class FilterUsingRegularExpressionCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        def done(needle):
            e = self.view.begin_edit()
            filter(self.view, e, needle, True)
            self.view.end_edit(e)

        cb = sublime.get_clipboard()
        sublime.active_window().show_input_panel("Filter file for lines matching: ", cb, done, None, None)
Run Code Online (Sandbox Code Playgroud)

Main.sublime-menu

[
    {
        "id": "edit",
        "children":
        [
            {"id": "wrap"},
            { "command": "filter" },
            { "command": "filter_using_regular_expression" }
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

Default (OSX).sublime-keymap

[  
    {   
        "keys": ["ctrl+shift+f"], "command": "filter"
    },
    {
        "keys": ["ctrl+shift+option+f"], "command": "filter_using_regular_expression"
    }
]  
Run Code Online (Sandbox Code Playgroud)

第二个插件命令“使用正则表达式过滤”将添加到“过滤器”菜单项下方。

Default.sublime-commands

[
    { "caption": "Filter Lines in File", "command": "filter" },
    { "caption": "Filter Lines in File Using Regular Expression", "command": "filter_using_regular_expression" }
]
Run Code Online (Sandbox Code Playgroud)

  • 你不想有一天把它作为一个包发布吗? (2认同)

All*_*LRH 52

现在有一个过滤行的插件https : //github.com/davidpeckham/FilterLines
它允许基于字符串或正则表达式进行过滤和代码折叠。


David Peckham 的 Sublime Text Filter Plugin

  • 刚刚安装了这个插件 - 非常适合这项工作。获取现有文件,让您输入过滤短语并将结果放在新选项卡中。 (5认同)
  • 同意,直到现在我一直梦想在我的文本编辑器中拥有这种功能。 (4认同)

And*_*rio 15

您可以使用 Sublime 的内置功能在 3 到 7 个按键中完成此操作(不包括要匹配的正则表达式)。

第 1 步:多选所有匹配的行

选项 1:多选包含子字符串的所有行

  1. 选择感兴趣的字符串。
  2. 点击Alt+F3以多选所有出现。
  3. 点击Ctrl+ L(将选择扩展到行)。

选项 2:多选与正则表达式匹配的所有行

  1. 点击Ctrl+F打开查找抽屉。
  2. 确保启用正则表达式匹配(Alt+R切换)。
  3. 输入正则表达式。
  4. 点击Alt+Enter以多选所有匹配项。
  5. 点击Ctrl+ L(将选择扩展到行)。

第 2 步:用这些线条做一些事情

选项 1:删除所有选中的行

  1. Ctrl+C复制。
  2. Ctrl+A选择全部。
  3. 点击Ctrl+V用匹配的行替换选择。

选项2:要摆脱所有的线选择

  1. 点击Ctrl+ Shift+ K(删除行)。

选项 3:将选定的行提取到新文件

  1. Ctrl+C复制。
  2. 点击Ctrl+N打开一个新文件。
  3. 点击Ctrl+V粘贴。