題 如何在Sublime Text 2中過濾包含字符串的行的文件?


我想過濾我在Sublime Text 2中編輯的文件,因為行包含某個字符串,如果可能的話包括正則表達式。

考慮以下文件:

foo bar
baz
qux
quuux baz

過濾時 ba,結果應該是:

foo bar
baz
quuux baz

我怎樣才能做到這一點?


72
2017-07-22 19:48


起源




答案:


Sublime Text 2是一個帶有的可擴展編輯器 Python API。您可以創建新命令(稱為 插件)並從UI中獲取它們。

添加基本​​過濾TextCommand插件

在Sublime Text 2中,選擇 工具»新插件 並輸入以下文本:

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)

另存為 filter.py 在 ~/Library/Application Support/Sublime Text 2/Packages/User

與UI集成

要將此插件添加到 編輯 菜單,選擇 首選項...»瀏覽包 並打開 User 夾。如果一個文件叫 Main.sublime-menu 不存在,創造它。在該文件中添加或設置以下文本:

[
    {
        "id": "edit",
        "children":
        [
            {"id": "wrap"},
            { "command": "filter" }
        ]
    }
]

這將插入 filter 命令調用(基本上, filter 變成了 FilterCommand().run(…) 對於插件調用和 過濾 對於菜單標籤)就在下方 wrap 命令。看到 這裡是第11步 更詳細的解釋為什麼會這樣。

要分配鍵盤快捷鍵,請打開並編輯該文件 Default (OSX).sublime-keymap 在OS X上,或其他系統的等效項,並輸入以下內容:

[  
    {   
        "keys": ["ctrl+shift+f"], "command": "filter"
    }  
]  

這將分配快捷方式 ^F 這個命令。


使命令顯示在 命令調色板,您需要創建一個名為的文件 Default.sublime-commands (或編輯現有的) User 夾。語法類似於剛剛編輯的菜單文件:

[
    { "caption": "Filter Lines in File", "command": "filter" }
]

多個條目(用大括號括起來)需要用逗號分隔。

行為和UI集成截圖

執行的命令將過濾作為選擇的一部分的所有行(整行,而不僅僅是選定的部分),或者,如果不存在選擇,則過濾整個緩衝區,用於輸入到輸入字段的子字符串(觸發命令後,default是 - 可能無用的多行 - 剪貼板)。它可以很容易地擴展到例如支持正則表達式,或只留下行  匹配某個表達式。

菜單項

Command in menu

命令調色板條目

Command with different label in Commands Palette

編輯

User entering text to filter file with

Result after executing the command

添加對正則表達式的支持

要添加對正則表達式的支持,請使用以下腳本和代碼段:

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)

Main.sublime-menu

[
    {
        "id": "edit",
        "children":
        [
            {"id": "wrap"},
            { "command": "filter" },
            { "command": "filter_using_regular_expression" }
        ]
    }
]

Default (OSX).sublime-keymap

[  
    {   
        "keys": ["ctrl+shift+f"], "command": "filter"
    },
    {
        "keys": ["ctrl+shift+option+f"], "command": "filter_using_regular_expression"
    }
]  

第二個插件命令, 使用正則表達式過濾 將在下面添加 過濾 菜單條目。

Default.sublime-commands

[
    { "caption": "Filter Lines in File", "command": "filter" },
    { "caption": "Filter Lines in File Using Regular Expression", "command": "filter_using_regular_expression" }
]

87
2017-07-22 19:48



你不想有一天將它作為包發布嗎? - slhck
@slhck某人已經做過(有適當的歸屬),請參閱NovicePhysicist的回答。從我在代碼中看到的內容來看,這個答案也得到了相當多的改進。 - Daniel Beck♦
很酷,我沒注意到! - slhck
SublimeText的主題是什麼,它提供了漂亮的顏色?或者只是改變窗口顏色? - pal4life
@ pal4life:這叫做 日曬(輕)。我認為Sublime Text甚至附帶它。我可能已經安裝了另一個,所以顏色可能不完全匹配。屏幕截圖位於OS X上,因此窗口邊框和標題欄位於此處。 - Daniel Beck♦


還有一個 窮人的線路過濾算法 (或者它是懶惰的?):

  1. 選擇 感興趣的字符串
  2. 擊中 Alt鍵+F3 在所有事件中進入多光標模式
  3. 擊中 控制+大號 選擇整行(在每個光標行上)
  4. 複製粘貼選擇到另一個緩衝區

75
2018-05-23 12:29



這是最簡單的解決方案。好樣的! - gillytech
謝謝!我不想盡可能多地安裝/學習另一個插件 - Alt + F3在我的肌肉記憶中,所以上面的解決方案對我來說實際上並不是那麼遙遠。 - Olof Bjarnason
您可以用一步替換步驟3和4:Ctrl + L. - Andres Riofrio
簡單的解決方案!我會將步驟3從Ctrl-L替換為Home,Shift-End因此在出現之間沒有空行。 - jslap
這改變了我的生活。什麼都不會再一樣了。 - Shawson


現在有一個 插入 過濾線: https://github.com/davidpeckham/FilterLines
它允許基於字符串或正則表達式進行過濾和代碼折疊。


Sublime Text Filter Plugin by David Peckham


46
2018-05-22 10:30



剛剛安裝了這個插件 - PERFECT就職。使用現有文件,您可以輸入過濾短語並將結果放入新選項卡中。 - Nick
同意,直到現在我才夢想在我的文本編輯器中擁有這種功能。 - Michael12345
這個插件非常棒! - Devid
來到這裡是因為同事提到了關於emacs的“Keep Lines”以及它的用處。甚至不知道我需要這個插件,絕對喜歡它! - brandon927


您可以使用Sublime的內置功能在3到7次擊鍵中執行此操作(不包括要匹配的正則表達式)。

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

選項1:多選所有包含子字符串的行

  1. 選擇感興趣的字符串。
  2. 擊中 Alt鍵+F3 多選所有出現。
  3. 擊中 按Ctrl+大號 (將選擇擴展到行)。

選項2:多選選擇與正則表達式匹配的所有行

  1. 擊中 按Ctrl+F 打開查找抽屜。
  2. 確保啟用正則表達式匹配(Alt鍵+[R 切換)。
  3. 輸入正則表達式。
  4. 擊中 Alt鍵+輸入 多選所有比賽。
  5. 擊中 按Ctrl+大號 (將選擇擴展到行)。

第2步:用這些線做點什麼

選項1:擺脫所有線路 不是 選

  1. 擊中 按Ctrl+C 複印。
  2. 擊中 按Ctrl+一個 選擇所有。
  3. 擊中 按Ctrl+V 用匹配的行替換選擇。

選項2:擺脫所有線條  選

  1. 擊中 按Ctrl+轉移+ķ (刪除行)。

選項3:將選定的行提取到新文件

  1. 擊中 按Ctrl+C 複印。
  2. 擊中 按Ctrl+ñ 打開一個新文件。
  3. 擊中 按Ctrl+V 粘貼。

12
2017-12-13 04:03



第1步為我做了。謝謝 - Devid
這是一個很好的命令列表! - chustar
超級,但有沒有辦法去除粘貼後的空白行? - Sergey Senkov
@SergeySenkov當然可以! (1)按Ctrl + F打開“查找”抽屜。 (2)確保啟用正則表達式匹配(Alt + R切換)。 (3)鍵入“\ n \ n +”(匹配兩個或多個連續的換行符)。 (4)按Alt + Enter可多選所有匹配項。 (5)按Enter鍵以使用單個換行符替換所有匹配項。 - Andres Riofrio