Sublime Text 2'de string içeren satırlar için bir dosyayı nasıl filtreleyebilirim?


74

Düzenli ifadeler de dahil olmak üzere mümkünse belirli bir dize içeren satırlar için Sublime Text 2'de düzenlediğim bir dosyayı filtrelemek istiyorum.

Aşağıdaki dosyayı göz önünde bulundurun:

foo bar
baz
qux
quuux baz

İçin filtrelendiğinde ba, sonuç şöyle olmalıdır:

foo bar
baz
quuux baz

Bunu nasıl yapabilirim?

Yanıtlar:


87

Sublime Text 2, Python API'si olan genişletilebilir bir editördür . Yeni komutlar ( Eklentiler adı verilen ) oluşturabilir ve kullanıcı arayüzünden kullanılabilir hale getirebilirsiniz.

Temel filtreleme TextCommand eklentisi ekleme

Sublime Text 2'de, Araçlar »Yeni Eklenti'yi seçin ve aşağıdaki metni girin:

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)

Farklı kaydet filter.pyde~/Library/Application Support/Sublime Text 2/Packages/User

UI ile entegrasyon

Bu eklentiyi Düzen menüsüne eklemek için Tercihler… »Paketlere gözatın ve Userklasörü açın . Eğer bir dosya Main.sublime-menubulunmuyorsa, onu oluşturun. Bu dosyaya aşağıdaki metni ekleyin veya ayarlayın:

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

Bu, filterkomutun hemen altına komut çağrısını (aslında, eklenti çağrısı için filterdönüştürülür ve menü etiketi için süzgeci ) ekler . Bunun nedeninin daha ayrıntılı bir açıklaması için buradaki 11. adıma bakın .FilterCommand().run(…)wrap

Klavye kısayolu atamak için, dosyayı Default (OSX).sublime-keymapOS X'te açıp düzenleyin veya diğer sistemler için eşdeğerini seçin ve aşağıdakini girin:

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

Bu, Fbu komuta kısayolu atar .


Komutun Komutlar Paletinde görünmesini sağlamak için Default.sublime-commands, Userklasörde bir dosya oluşturmanız (veya var olanı düzenlemek) gerekir . Sözdizimi, az önce düzenlediğiniz menü dosyasına benzer:

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

Birden çok girişin (küme parantezi içine alınmış) virgüllerle ayrılması gerekir.

 Davranış ve UI entegrasyon ekran görüntüleri

Uygulandığı gibi komut, bir seçimin parçası olan tüm satırları (yalnızca seçilen bölümleri değil tüm satırları) veya seçim yoksa, giriş alanına girilen bir alt dizinin tüm arabelleğini filtreleyecektir. varsayılan, komut tetiklendikten sonra - muhtemelen işe yaramaz çok satırlı - panoya) 'dir. Kolayca destek düzenli ifadeler örneğin, ya da sadece hattından çıkan uzatılabilir değil belli bir ifade ile eşleşen.

Menü seçeneği

Menüdeki komut

Komutlar palet girişi

Komutlar Paletinde farklı etiketli komutlar

Editör

İle dosya filtrelemek için kullanıcı metin girerek

Komutu yürüttükten sonra sonuç

Normal İfadeler için destek ekleme

Normal ifadeler için destek eklemek için aşağıdaki komut dosyalarını ve pasajları kullanın:

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

İkinci bir eklenti komutu, Düzenli İfade Kullanarak Filtrele Filtre menüsü girişinin altına eklenir .

Default.sublime-commands:

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

2
Bunu bir gün paket olarak yayınlamak istemiyor musunuz?
slhck

1
@slhck Birisi zaten yapmış (uygun nitelikte), NovicePhysicist'in cevabına bakınız. Kodda okuduklarımdan itibaren, bu cevabın üzerinde de biraz geliştirildi.
Daniel Beck

Harika, bunu farketmedim!
slhck

Bu hoş renkleri veren SublimeText ile sahip olduğunuz tema nedir? Yoksa sadece pencere rengini mi değiştiriyor?
pal4life

1
@ pal4life: Buna Solarized (Işık) denir . Bence Sublime Text onunla birlikte gelir. Yine de bir alternatif daha kurmuş olabilirim, bu yüzden renkler tam olarak aynı olmayabilir. Ekran görüntüleri OS X’de, bu nedenle pencere kenarlığı ve başlık çubuğunun bulunduğu yer.
Daniel Beck

83

Orada bir de yoksul adamın çizgi filtreleme algoritması (veya tembel?):

  1. İlgilendiğiniz dizeyi seçin
  2. Hit Alt+ F3geçtiği tüm çoklu imleç moduna geçmek için
  3. Çizginin tamamını seçmek için Control+ Ldüğmesine basın (her imleç çizgisinde)
  4. Kopyala yapıştır seçimini başka bir ara belleğe

2
Bu hemen hemen en basit çözüm. Bravo!
gillytech

Teşekkür ederim! Mümkün olduğunca başka bir eklenti kurmak / öğrenmek zorunda kalmamayı tercih ediyorum - Alt + F3 kas hafızamda, bu yüzden yukarıdaki çözüm aslında benim için o kadar da zorlanmıyor.
Olof Bjarnason

3. ve 4. adımları tek bir adımla değiştirebilirsiniz: Ctrl + L.
Andres Riofrio

1
Güzel basit bir çözüm! 3. adımı Ctrl-L'den Ana Sayfa, Shift-End'e değiştiririm. Bu yüzden olaylar arasında boş satır kalmaz.
jslap

4
Bu hayatımı daha iyi hale getirdi. Hiçbir şey bir daha asla eskisi gibi olmayacak.
Shawson

49

Artık satırları filtrelemek için bir eklenti var : https://github.com/davidpeckham/FilterLines
Dizelere veya normal ifadelere göre filtreleme ve kod katlama sağlar.


David Peckham tarafından Yüce Metin Filtre Eklentisi


4
Sadece bu eklentiyi yükledim - iş için mükemmel. Mevcut bir dosyayı alır, bir filtre öbeği girmenize izin verir ve sonuçları yeni bir sekmeye yerleştirir.
Nick

4
Kabul ediyorum, şimdiye kadar sadece metin editörümde bu tür bir işleve sahip olmayı hayal ettim.
Michael12345

1
Bu eklenti gerçekten harika!
Devid

Bir iş arkadaşı emacs için "Hatları Tut" hakkında bir şeyden bahsettiği ve ne kadar faydalı olduğu için buraya geldi. Bu eklentiye ihtiyacım olduğunu bile bilmiyordum, kesinlikle seviyorum!
brandon927,

14

Sublime'ın yerleşik yeteneklerini, bunu 3 ila 7 tuş vuruşunda (eşleştirilecek regex dahil değil) yapmak için kullanabilirsiniz.

Adım 1: Tüm eşleşen satırları çoklu seç

Seçenek 1: Bir alt dize içeren tüm satırları çoklu seçmek için

  1. İlgilendiğiniz dizeyi seçin.
  2. Hit Alt+ F3tüm oluşumları çoklu seçin.
  3. Hit Ctrl+ L(Seçimi Satıra Genişlet).

Seçenek 2: Bir regexp ile eşleşen tüm satırları çoklu seçmek için

  1. Bul çekmecesini açmak için Ctrl+ Ftuşuna basın .
  2. Normal İfade eşlemesinin etkin olduğundan emin olun ( Alt+ Rile geçiş yap).
  3. Normal ifadeyi yazın.
  4. Hit Alt+ Entertüm eşleşmeleri çoklu seçin.
  5. Hit Ctrl+ L(Seçimi Satıra Genişlet).

Adım 2: Bu çizgilerle bir şeyler yapın

1. Seçenek: tüm hatları kurtulmak için değil seçilmiş

  1. Hit Ctrl+ Ckopyalamak.
  2. Hit Ctrl+ ATümünü seçmek için.
  3. Hit Ctrl+ Vuygun çizgilerle seçimi yerine.

Seçenek 2: Seçilen tüm satırlardan kurtulmak için

  1. Hit Ctrl+ Shift+ K(Hattı Sil).

Seçenek 3: Seçilen satırları yeni bir dosyaya çıkarmak için

  1. Hit Ctrl+ Ckopyalamak.
  2. Yeni bir dosya açmak için Ctrl+ Ntuşuna basın .
  3. Hit Ctrl+ Vyapıştırın.

Bu, komutların mükemmel bir listesi!
chustar

Süper, ama yapıştırdıktan sonra boş satırları kaldırmak için yolu var mı?
Sergey Senkov

1
@SergeySenkov Tabii! (1) Bul çekmecesini açmak için Ctrl + F tuşlarına basın. (2) Normal İfade eşlemesinin etkin olduğundan emin olun (geçiş yapmak için Alt + R). (3) "\ n \ n +" yazın (üst üste iki veya daha fazla yeni satırla eşleşir). (4) Tüm karşılaşmaları çoklu seçmek için Alt + Enter tuşlarına basın. (5) Tüm karşılaşmaları tek bir yeni satırla değiştirmek için Enter tuşuna basın.
Andres Riofrio
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.