سؤال كيف يمكنني تصفية ملف للخطوط التي تحتوي على سلسلة في نص Sublime 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 هو محرر موسع مع بايثون API. يمكنك إنشاء أوامر جديدة (تسمى الإضافات) وجعلها متاحة من واجهة المستخدم.

إضافة التصفية الأساسية 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

التكامل مع واجهة المستخدم

لإضافة هذا البرنامج المساعد إلى تصحيح القائمة ، حدد التفضيلات ... »استعرض الحزم وفتح 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" }
]

يجب فصل الإدخالات المتعددة (الموجودة بين الأقواس المتعرجة) بفواصل.

لقطات شاشة دمج وتكامل واجهة المستخدم

يقوم الأمر ، كما تم تنفيذه ، بتصفية كل الأسطر التي تشكل جزءًا من التحديد (الخطوط الكاملة ، وليس الأجزاء المحددة فقط) ، أو ، إذا لم يكن هناك تحديد ، المخزن المؤقت بأكمله ، لسلسلة فرعية يتم إدخالها إلى حقل الإدخال ( الافتراضي هو - ربما غير مجدية متعدد الخطوط - الحافظة بعد تشغيل الأمر. يمكن تمديدها بسهولة على سبيل المثال. دعم التعبيرات العادية ، أو ترك الخطوط فقط ليس مطابقة تعبير معين.

عنصر القائمة

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: إنه يسمى مشحم (خفيف). أعتقد أن سوبلم نص حتى يأتي معها. ربما قمت بتثبيت بديل على الرغم من ذلك ، فقد لا تتطابق الألوان تمامًا. توجد لقطات الشاشة على OS X ، ومن هنا يكون هناك حد النافذة وشريط العنوان. - Daniel Beck♦


هنالك أيضا خوارزمية تصفية خط الرجل الفقير (أم أنها كسولة؟):

  1. تحديد سلسلة من الاهتمام
  2. نجاح البديل+F3 للذهاب إلى وضع المؤشر المتعدد على جميع الوقائع
  3. نجاح مراقبة+L لتحديد خط كامل (على كل سطر مؤشر)
  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



فقط تثبيت هذا البرنامج المساعد - الكمال لهذا المنصب. يتيح ملفًا حاليًا ، ويتيح لك إدخال عبارة التصفية ووضع النتائج في علامة تبويب جديدة. - Nick
متفق عليه ، حتى الآن لم أكن أحلم إلا من هذا النوع من الوظائف في محرر النصوص الخاص بي. - Michael12345
هذا البرنامج المساعد رائع حقا! - Devid
جئت إلى هنا لأن أحد الزملاء ذكر شيئًا عن "الاحتفاظ بالخطوط" بالنسبة إلى إيماكس ومدى فائدته. لم أكن أعرف حتى أنني بحاجة إلى هذا البرنامج المساعد ، أحب ذلك تماما! - brandon927


يمكنك استخدام إمكانات Sublime المضمنة للقيام بذلك في 3 إلى 7 ضربات مفاتيح (لا تشمل التعبير المعتاد ليتم مطابقته).

الخطوة 1: التحديد المتعدد لكل الخطوط المطابقة

الخيار 1: لتحديد متعدد الخطوط التي تحتوي على سلسلة فرعية

  1. حدد سلسلة الاهتمام.
  2. نجاح البديل+F3 لتحديد متعددة لجميع التواجدات.
  3. نجاح السيطرة+L (قم بتوسيع التحديد إلى خط).

الخيار 2: لتحديد متعدد الأسطر التي تتطابق مع regexp

  1. نجاح السيطرة+F لفتح درج البحث.
  2. تأكد من تمكين مطابقة التعبير العادي (البديل+R للتبديل).
  3. اكتب في التعبير العادي.
  4. نجاح البديل+أدخل لتحديد متعدد جميع المباريات.
  5. نجاح السيطرة+L (قم بتوسيع التحديد إلى خط).

الخطوة 2: افعل شيئًا باستخدام هذه الخطوط

الخيار 1: للتخلص من جميع الخطوط غير صحيح المحدد

  1. نجاح السيطرة+C لنسخ.
  2. نجاح السيطرة+ا لتحديد الكل.
  3. نجاح السيطرة+الخامس لاستبدال التحديد بالخطوط المتطابقة.

الخيار 2: للتخلص من جميع الخطوط هي المحدد

  1. نجاح السيطرة+تحول+ك (حذف الخط).

الخيار 3: لاستخراج الخطوط المختارة إلى ملف جديد

  1. نجاح السيطرة+C لنسخ.
  2. نجاح السيطرة+N لفتح ملف جديد.
  3. نجاح السيطرة+الخامس لصق.

12
2017-12-13 04:03



فعلت الخطوة 1 بالنسبة لي. شكر - Devid
هذه قائمة ممتازة من الأوامر! - chustar
سوبر ، ولكن هل هناك طريقة لإزالة الخطوط الفارغة بعد اللصق؟ - Sergey Senkov
تضمين التغريدة (1) اضغط Ctrl + F لفتح درج البحث. (2) تأكد من تمكين مطابقة التعبير العادي (Alt + R للتبديل). (3) اكتب "\ n \ n +" (تطابق اثنين أو أكثر من الخطوط الجديدة المتتالية). (4) اضغط على Alt + Enter لتحديد متعدد التطابقات. (5) اضغط على Enter لاستبدال كل التطابقات بخط جديد واحد. - Andres Riofrio