Làm cách nào tôi có thể lọc một tệp cho các dòng chứa một chuỗi trong Sublime Text 2?


74

Tôi muốn lọc một tệp tôi đang chỉnh sửa trong Sublime Text 2 cho các dòng chứa một chuỗi nhất định, nếu có thể bao gồm các biểu thức thông thường.

Hãy xem xét các tập tin sau:

foo bar
baz
qux
quuux baz

Khi được lọc ba, kết quả sẽ là:

foo bar
baz
quuux baz

Làm thế nào tôi có thể làm điều đó?

Câu trả lời:


87

Sublime Text 2 là một trình soạn thảo có thể mở rộng với API Python . Bạn có thể tạo các lệnh mới (được gọi là Plugins ) và cung cấp chúng từ UI.

Thêm plugin lọc TextCommand cơ bản

Trong Sublime Text 2, chọn Công cụ »Plugin mới và nhập văn bản sau:

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)

Lưu như filter.pytrong~/Library/Application Support/Sublime Text 2/Packages/User

Tích hợp với giao diện người dùng

Để thêm plugin này vào menu Chỉnh sửa , chọn Tùy chọn '»Duyệt Gói và mở Userthư mục. Nếu một tệp được gọi là Main.sublime-menukhông tồn tại, tạo nó. Thêm hoặc đặt văn bản sau vào tệp đó:

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

Điều này sẽ chèn filterlệnh gọi (về cơ bản, filterđược chuyển đổi thành FilterCommand().run(…)lệnh gọi plugin và Bộ lọc cho nhãn menu) ngay bên dưới wraplệnh. Xem bước 11 ở đây để được giải thích chi tiết hơn tại sao lại như vậy.

Để gán phím tắt, hãy mở và chỉnh sửa tệp Default (OSX).sublime-keymaptrên OS X hoặc tương đương với các hệ thống khác và nhập thông tin sau:

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

Điều này sẽ gán phím tắt Fcho lệnh này.


Để làm cho lệnh hiển thị trong Bảng lệnh , bạn cần tạo một tệp có tên Default.sublime-commands(hoặc chỉnh sửa tệp hiện có) trong Userthư mục. Cú pháp tương tự như tệp menu bạn vừa chỉnh sửa:

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

Nhiều mục (được bao quanh bởi dấu ngoặc nhọn) cần được phân tách bằng dấu phẩy.

 Ảnh chụp màn hình tích hợp UI và hành vi

Lệnh, như được triển khai, sẽ lọc tất cả các dòng là một phần của lựa chọn (toàn bộ các dòng, không chỉ các phần được chọn) hoặc, nếu không có lựa chọn nào tồn tại, toàn bộ bộ đệm, cho một chuỗi con được nhập vào trường đầu vào ( mặc định là - có thể vô dụng nhiều dòng - clipboard) sau khi lệnh được kích hoạt. Nó có thể dễ dàng được mở rộng để hỗ trợ các biểu thức thông thường hoặc chỉ để lại các dòng không khớp với một biểu thức nhất định.

Mục menu

Lệnh trong menu

Lệnh bảng màu

Lệnh với nhãn khác nhau trong Commands Palette

Biên tập viên

Người dùng nhập văn bản để lọc tệp với

Kết quả sau khi thực hiện lệnh

Thêm hỗ trợ cho Biểu thức chính quy

Để thêm hỗ trợ cho các biểu thức thông thường, thay vào đó, hãy sử dụng các đoạn mã và đoạn mã sau:

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

Lệnh plugin thứ hai, Bộ lọc sử dụng Biểu thức chính quy sẽ được thêm vào bên dưới mục trình đơn Bộ lọc .

Default.sublime-commands:

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

2
Bạn không muốn xuất bản nó như một gói một ngày?
slhck

1
@slhck Ai đó đã làm (với sự ghi nhận phù hợp), xem câu trả lời của NovicePhysicist. Từ những gì tôi đọc được trong mã, nó cũng được cải thiện khá nhiều so với câu trả lời này.
Daniel Beck

Thật tuyệt, tôi đã không nhận ra điều đó!
slhck

Chủ đề bạn có với SublimeText mang lại màu sắc đẹp là gì? Hay chỉ là thay đổi màu cửa sổ?
pal4life

1
@ pal4life: Nó được gọi là Solarized (Ánh sáng) . Tôi nghĩ Sublime Text thậm chí còn xuất xưởng với nó. Tôi có thể đã cài đặt một cái thay thế, vì vậy màu sắc có thể không khớp chính xác. Ảnh chụp màn hình trên OS X, vì vậy đó là đường viền cửa sổ và thanh tiêu đề.
Daniel Beck

83

Ngoài ra còn có thuật toán lọc dòng của một người nghèo (hoặc là lười biếng?):

  1. Chọn chuỗi quan tâm
  2. Nhấn Alt+ F3để chuyển sang chế độ đa con trỏ trên tất cả các lần xuất hiện
  3. Nhấn Control+ Lđể chọn toàn bộ dòng (trên mỗi dòng con trỏ)
  4. Sao chép-dán lựa chọn vào bộ đệm khác

2
Đây là khá nhiều giải pháp đơn giản nhất. Bravo!
gillytech

Cảm ơn bạn! Tôi không cần phải cài đặt / tìm hiểu một plugin khác càng nhiều càng tốt - Alt + F3 nằm trong bộ nhớ cơ của tôi vì vậy giải pháp trên thực sự không quá xa vời đối với tôi.
Olof Bjarnason

Bạn có thể thay thế Bước 3 và 4 bằng một bước duy nhất: Ctrl + L.
Andres Riofrio

1
Giải pháp đơn giản tốt đẹp! Tôi sẽ thay thế bước 3 từ Ctrl-L sang Home, Shift-End Vì vậy, không có dòng nào trống giữa các lần xuất hiện.
jslap

4
Điều này đã thay đổi cuộc sống của tôi tốt hơn. Không có gì sẽ lại như cũ.
Shawson

49

Hiện tại có một plugin để lọc các dòng: https://github.com/davidpeckham/FilterLines
Nó cho phép lọc và gấp mã dựa trên các chuỗi hoặc biểu thức thông thường.


Plugin lọc văn bản tuyệt vời của David Peckham


4
Chỉ cần cài đặt plugin này - HOÀN HẢO cho công việc. Lấy một tệp hiện có, cho phép bạn nhập cụm từ bộ lọc và đặt kết quả vào một tab mới.
Nick

4
Đồng ý, cho đến bây giờ tôi chỉ mơ ước có loại chức năng này trong trình soạn thảo văn bản của mình.
Michael12345

1
Plugin này thực sự tuyệt vời!
Devid

Đến đây vì một đồng nghiệp đã đề cập một vài điều về "Keep Lines" cho emacs và nó hữu ích như thế nào. Thậm chí không biết tôi cần plugin này, hoàn toàn thích nó!
brandon927

14

Bạn có thể sử dụng các khả năng tích hợp của Sublime để thực hiện việc này trong 3 đến 7 nét chính (không bao gồm biểu thức chính được khớp).

Bước 1: Đa lựa chọn tất cả các dòng phù hợp

Tùy chọn 1: Để đa lựa chọn tất cả các dòng có chứa một chuỗi con

  1. Chọn chuỗi quan tâm.
  2. Nhấn Alt+ F3để đa lựa chọn tất cả các lần xuất hiện.
  3. Lượt truy cập Ctrl+ L(Mở rộng lựa chọn thành dòng).

Tùy chọn 2: Để đa lựa chọn tất cả các dòng khớp với biểu thức chính

  1. Nhấn Ctrl+ Fđể mở ngăn Tìm.
  2. Đảm bảo kết hợp Biểu thức chính quy được bật ( Alt+ Rchuyển đổi).
  3. Gõ vào biểu thức chính quy.
  4. Nhấn Alt+ Enterđể đa lựa chọn tất cả các trận đấu.
  5. Lượt truy cập Ctrl+ L(Mở rộng lựa chọn thành dòng).

Bước 2: Làm gì đó với những dòng đó

Tùy chọn 1: Để thoát khỏi tất cả các dòng không được chọn

  1. Nhấn Ctrl+ Cđể sao chép.
  2. Nhấn Ctrl+ Ađể chọn tất cả.
  3. Nhấn Ctrl+ Vđể thay thế lựa chọn bằng các dòng khớp.

Tùy chọn 2: Để thoát khỏi tất cả các dòng được chọn

  1. Lượt Ctrl+ Shift+ K(Xóa dòng).

Tùy chọn 3: Để trích xuất các dòng được chọn vào một tệp mới

  1. Nhấn Ctrl+ Cđể sao chép.
  2. Nhấn Ctrl+ Nđể mở tệp mới.
  3. Nhấn Ctrl+ Vđể dán.

Đây là một danh sách tuyệt vời của các lệnh!
chustar

Siêu, nhưng có cách nào để loại bỏ các dòng trống sau khi dán?
Sergey Senkov

1
@SergeySenkov Chắc chắn! (1) Nhấn Ctrl + F để mở ngăn Tìm. (2) Đảm bảo kết hợp Biểu thức chính quy được bật (Alt + R để chuyển đổi). (3) Nhập "\ n \ n +" (khớp hai hoặc nhiều dòng mới liên tiếp). (4) Nhấn Alt + Enter để đa lựa chọn tất cả các trận đấu. (5) Nhấn Enter để thay thế tất cả các trận đấu bằng một dòng mới.
Andres Riofrio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.