Question Comment puis-je filtrer un fichier pour les lignes contenant une chaîne dans Sublime Text 2?


Je veux filtrer un fichier que je modifie dans Sublime Le texte 2 pour les lignes contient une certaine chaîne, y compris si possible des expressions régulières.

Considérez le fichier suivant:

foo bar
baz
qux
quuux baz

Lorsque filtré pour ba, le résultat devrait être:

foo bar
baz
quuux baz

Comment puis je faire ça?


68
2017-07-22 19:48


origine




Réponses:


Sublime Text 2 est un éditeur extensible avec API Python. Vous pouvez créer de nouvelles commandes (appelées Plugins) et les rendre disponibles à partir de l'interface utilisateur.

Ajout d'un filtre de base TextCommand plugin

Dans Sublime Text 2, sélectionnez Outils »Nouveau plugin et entrez le texte suivant:

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)

Enregistrer sous filter.py dans ~/Library/Application Support/Sublime Text 2/Packages/User

Intégration avec l'interface utilisateur

Pour ajouter ce plugin au modifier menu, sélectionnez Préférences ... »Parcourir les paquets et ouvrez le User dossier. Si un fichier appelé Main.sublime-menu n'existe pas, créez-le. Ajoutez ou définissez le texte suivant dans ce fichier:

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

Cela va insérer le filter appel de commande (essentiellement, filter est transformé en FilterCommand().run(…) pour l'appel du plugin et Filtre pour l'étiquette de menu) juste en dessous du wrap commander. Voir étape 11 ici pour une explication plus détaillée, pourquoi?

Pour attribuer un raccourci clavier, ouvrez et modifiez le fichier Default (OSX).sublime-keymap sous OS X, ou l'équivalent pour d'autres systèmes, et entrez les informations suivantes:

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

Cela affectera le raccourci ^F à cette commande.


Pour que la commande apparaisse dans le Palette de commandes, vous devez créer un fichier nommé Default.sublime-commands (ou éditer un existant) dans le User dossier. La syntaxe est similaire au fichier de menu que vous venez de modifier:

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

Les entrées multiples (entre accolades) doivent être séparées par des virgules.

Captures d'écran du comportement et de l'intégration de l'interface utilisateur

La commande, telle qu'elle est implémentée, filtre toutes les lignes faisant partie d'une sélection (les lignes entières, pas seulement les parties sélectionnées) ou, si aucune sélection n'existe, la totalité du tampon, pour une sous-chaîne entrée dans le champ d'entrée ( la valeur par défaut est le presse-papiers multi-lignes - éventuellement inutile - après le déclenchement de la commande. Il peut facilement être étendu à par ex. soutenir des expressions régulières, ou ne laisser que des lignes ne pas correspondant à une certaine expression.

Élément du menu

Command in menu

Entrée de la palette des commandes

Command with different label in Commands Palette

Éditeur

User entering text to filter file with

Result after executing the command

Ajout du support pour les expressions régulières

Pour ajouter la prise en charge des expressions régulières, utilisez plutôt les scripts et extraits suivants:

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

Une deuxième commande de plugin, Filtrer en utilisant une expression régulière sera ajouté en dessous du Filtre entrée de menu.

Default.sublime-commands:

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

86
2017-07-22 19:48



Ne souhaitez-vous pas publier cela comme un paquet un jour? - slhck
@slhck Quelqu'un l'a déjà fait (avec l'attribution appropriée), voir la réponse de NovicePhysicist. D'après ce que j'ai lu dans le code, cette réponse a également été améliorée. - Daniel Beck♦
Cool, je n'ai pas remarqué ça! - slhck
Quel est ce thème avec le SublimeText qui donne de jolies couleurs? Ou est-ce juste changer la couleur de la fenêtre? - pal4life
@ pal4life: On appelle ça Solarisé (Lumière). Je pense que Sublime Text est même livré avec. J'aurais peut-être installé une alternative, donc les couleurs pourraient ne pas correspondre exactement. Les captures d'écran se trouvent sous OS X, d'où la provenance de la bordure de la fenêtre et de la barre de titre. - Daniel Beck♦


Il y a aussi algorithme de filtrage de ligne de pauvre homme (ou est-ce paresseux?):

  1. Sélectionner chaîne d'intérêt
  2. Frappé Alt+F3 passer en mode multi-curseur sur toutes les occurrences
  3. Frappé Contrôle+L pour sélectionner une ligne entière (sur chaque ligne de curseur)
  4. Copier-coller la sélection dans un autre tampon

72
2018-05-23 12:29



C'est à peu près la solution la plus simple. Bravo! - gillytech
Je vous remercie! Je préfère ne pas avoir à installer / apprendre un autre plugin pour autant que possible - Alt + F3 est dans ma mémoire musculaire, donc la solution ci-dessus n'est en fait pas si loin pour moi. - Olof Bjarnason
Vous pouvez remplacer les étapes 3 et 4 par une seule étape: Ctrl + L. - Andres Riofrio
Belle solution simple! Je remplacerais l'étape 3 de Ctrl-L à Home, Shift-End Il n'y a donc pas de lignes vides entre les occurrences. - jslap
Cela a changé ma vie pour le mieux. Rien ne sera plus jamais pareil. - Shawson


Il y a maintenant un brancher pour filtrer les lignes: https://github.com/davidpeckham/FilterLines
Il permet le filtrage et le pliage du code en fonction de chaînes ou d'expressions régulières.


Sublime Text Filter Plugin by David Peckham


43
2018-05-22 10:30



Juste installé ce plugin - PERFECT pour le travail. Prend un fichier existant, vous permet d'entrer une phrase de filtre et place les résultats dans un nouvel onglet. - Nick
D'accord, jusqu'à présent, je n'avais jamais rêvé d'avoir ce genre de fonctionnalités dans mon éditeur de texte. - Michael12345
Ce plugin est vraiment génial! - Devid
Je suis venu ici car un collègue a mentionné quelque chose à propos de "Keep Lines" pour emacs et à quel point il est utile. Je ne savais même pas que j'avais besoin de ce plugin, j'adore ça! - brandon927


Vous pouvez utiliser les fonctionnalités intégrées de Sublime pour le faire en 3 à 7 touches (sans inclure la regex à faire correspondre).

Étape 1: sélectionnez toutes les lignes correspondantes

Option 1: sélectionner plusieurs lignes contenant une sous-chaîne

  1. Sélectionnez la chaîne d'intérêt.
  2. Frappé Alt+F3 multi-sélectionner toutes les occurrences.
  3. Frappé Ctrl+L (Développez Sélection à la ligne).

Option 2: Pour sélectionner plusieurs lignes correspondant à une expression régulière

  1. Frappé Ctrl+F pour ouvrir le tiroir Find.
  2. Assurez-vous que la correspondance des expressions régulières est activée (Alt+R pour basculer).
  3. Tapez l'expression régulière.
  4. Frappé Alt+Entrer pour sélectionner tous les matchs.
  5. Frappé Ctrl+L (Développez Sélection à la ligne).

Étape 2: Faites quelque chose avec ces lignes

Option 1: se débarrasser de toutes les lignes ne sont pas choisi

  1. Frappé Ctrl+C copier.
  2. Frappé Ctrl+UNE pour tout sélectionner.
  3. Frappé Ctrl+V pour remplacer la sélection par les lignes correspondantes.

Option 2: se débarrasser de toutes les lignes sont choisi

  1. Frappé Ctrl+Décalage+K (Supprimer la ligne).

Option 3: extraire les lignes sélectionnées dans un nouveau fichier

  1. Frappé Ctrl+C copier.
  2. Frappé Ctrl+N ouvrir un nouveau fichier.
  3. Frappé Ctrl+V coller.

12
2017-12-13 04:03



L'étape 1 l'a fait pour moi. Merci - Devid
C'est une excellente liste de commandes! - chustar
Super, mais y a-t-il moyen de supprimer les lignes vides après le collage? - Sergey Senkov
@SergeySenkov Sûr! (1) Appuyez sur Ctrl + F pour ouvrir le tiroir Rechercher. (2) Assurez-vous que la correspondance des expressions régulières est activée (Alt + R pour basculer). (3) Tapez "\ n \ n +" (correspond à deux nouvelles lignes consécutives ou plus). (4) Appuyez sur Alt + Entrée pour sélectionner tous les matchs. (5) Appuyez sur Entrée pour remplacer tous les matchs par une nouvelle ligne. - Andres Riofrio