Sublime Text 2の文字列を含む行のファイルをフィルタリングするにはどうすればよいですか?


74

Sublime Text 2で編集しているファイルをフィルター処理して、可能であれば正規表現を含む特定の文字列を含む行を探します。

次のファイルを検討してください。

foo bar
baz
qux
quuux baz

でフィルタリングするbaと、結果は次のようになります。

foo bar
baz
quuux baz

どうやってやるの?

回答:


87

Sublime Text 2は、Python APIを備えた拡張可能なエディターです。新しいコマンド(Plugins)を作成し、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変換され、メニューラベル用にフィルター処理されます)。その理由の詳細については、ステップ11を参照してください。FilterCommand().run(…)wrap

キーボードショートカットを割り当てるには、Default (OSX).sublime-keymapOS Xまたは他のシステムの同等のファイルを開いて編集し、次のように入力します。

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

これによりF、このコマンドにショートカットが割り当てられます。


コマンドパレットにコマンドを表示するにはDefault.sublime-commandsUserフォルダーに名前のファイルを作成(または既存のファイルを編集)する必要があります。構文は、編集したばかりのメニューファイルに似ています。

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

複数のエントリ(中括弧で囲まれている)は、コンマで区切る必要があります。

 動作と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)

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"
    }
]  

2番目のプラグインコマンド、正規表現使用しフィルターがフィルターメニューエントリの下に追加されます。

Default.sublime-commands

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

2
いつかこれをパッケージとして公開しませんか?
slhck

1
@slhck誰かがすでに(適切な属性で)しました。NovicePhysicistの答えを参照してください。私がコードで読んだことから、この回答よりもかなり改善されました。
ダニエルベック

クール、私はそれに気づかなかった!
slhck

素敵な色を与えるSublimeTextのテーマは何ですか?または、ウィンドウの色を変更するだけですか?
pal4life 14

1
@ pal4life:Solarized(Light)と呼ばれます。Sublime Textにも同梱されていると思います。ただし、別のものをインストールした可能性があるため、色が完全に一致しない場合があります。スクリーンショットはOS X上にあるため、そこからウィンドウの境界線とタイトルバーが表示されます。
ダニエルベック

83

貧乏人のラインフィルタリングアルゴリズムもあります(または、怠け者ですか?)。

  1. 関心のある文字列を選択
  2. ヒットAlt+ F3すべての出現にマルチカーソルモードに入ります
  3. ヒットControl+ L(すべてのカーソルライン上の)行全体を選択するには
  4. 選択範囲を別のバッファにコピーして貼り付けます

2
これはほとんど最も簡単なソリューションです。ブラボー!
gillytech

ありがとうございました!可能な限り別のプラグインをインストール/学習する必要はありません。Alt+ F3は私の筋肉の記憶にあるため、上記のソリューションは実際にはそれほど得られません。
オロフBjarnason 14年

手順3と4を単一の手順Ctrl + Lに置き換えることができます。
アンドレスリオフリオ

1
素敵なシンプルなソリューション!手順3をCtrl-LからHome、Shift-Endに置き換えます。したがって、オカレンス間に空行はありません。
jslap

4
これは私の人生をより良く変えました。二度と同じものはありません。
ショーソン

49

現在、行をフィルタリングするためのプラグインがあります:https : //github.com/davidpeckham/FilterLines
文字列または正規表現に基づいたフィルタリングとコードの折りたたみを可能にします。


David PeckhamによるSublime Text Filterプラグイン


4
このプラグインをインストールしました-ジョブに最適です。既存のファイルを取得し、フィルターフレーズを入力して、結果を新しいタブに配置します。
ニック

4
同意して、今まで私はテキストエディタでこの種の機能を持つことを夢見ていただけです。
Michael12345 14年

1
このプラグインは本当に素晴らしいです!
DEVID

ここに来たのは、同僚がemacsの「行を維持する」ことと、それがどれほど便利かについて言及したからです。このプラグインが必要だとさえ知らなかったので、絶対に気に入ってください!
brandon927

14

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貼り付けます。

これはコマンドの優れたリストです!
chustar

素晴らしいですが、貼り付け後に空白行を削除する方法はありますか?
セルゲイセンコフ16

1
@SergeySenkov確かに!(1)Ctrl + Fを押して検索ドロワーを開きます。(2)正規表現の一致が有効になっていることを確認します(Alt + Rで切り替え)。(3)「\ n \ n +」と入力します(2つ以上の連続する改行に一致します)。(4)すべての一致を複数選択するには、Alt + Enterを押します。(5)Enterキーを押して、一致するすべての行を単一の改行に置き換えます。
アンドレスリオフリオ16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.