ฉันจะกรองไฟล์สำหรับบรรทัดที่มีสตริงใน Sublime Text 2 ได้อย่างไร


74

ฉันต้องการกรองไฟล์ที่ฉันกำลังแก้ไขใน Sublime Text 2 สำหรับบรรทัดมีสตริงที่แน่นอนถ้าเป็นไปได้รวมถึงนิพจน์ทั่วไป

พิจารณาไฟล์ต่อไปนี้:

foo bar
baz
qux
quuux baz

เมื่อกรองbaแล้วผลลัพธ์ควรเป็น:

foo bar
baz
quuux baz

ฉันจะทำสิ่งนั้นได้อย่างไร

คำตอบ:


87

Sublime Text 2 เป็นบรรณาธิการขยายกับงูหลาม API คุณสามารถสร้างคำสั่งใหม่ (เรียกว่าปลั๊กอิน ) และทำให้พร้อมใช้งานจาก UI

การเพิ่มปลั๊กอินการกรองข้อความพื้นฐาน

ใน 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จะถูกเปลี่ยนเป็นFilterCommand().run(…)สำหรับการเรียกใช้ปลั๊กอินและตัวกรองสำหรับป้ายชื่อเมนู) ใต้wrapคำสั่ง ดูขั้นตอนที่ 11 ที่นี่สำหรับคำอธิบายโดยละเอียดเพิ่มเติมว่าทำไม

หากต้องการกำหนดแป้นพิมพ์ลัดให้เปิดและแก้ไขไฟล์Default (OSX).sublime-keymapใน OS X หรือเทียบเท่าสำหรับระบบอื่นแล้วป้อนข้อมูลต่อไปนี้:

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

สิ่งนี้จะกำหนดทางลัดFให้กับคำสั่งนี้


ในการทำให้คำสั่งปรากฏในCommands Paletteคุณจะต้องสร้างไฟล์ชื่อDefault.sublime-commands(หรือแก้ไขไฟล์ที่มีอยู่) ในUserโฟลเดอร์ ไวยากรณ์คล้ายกับไฟล์เมนูที่คุณเพิ่งแก้ไข:

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

คำสั่งปลั๊กอินที่สองกรองโดยใช้นิพจน์ปกติจะถูกเพิ่มไว้ใต้รายการเมนูตัวกรอง

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 จากสิ่งที่ฉันอ่านในโค้ดมันได้รับการปรับปรุงให้ดีขึ้นกว่าคำตอบนี้เล็กน้อย
Daniel Beck

เจ๋งฉันไม่ได้สังเกตสิ่งนั้น!
slhck

ชุดรูปแบบที่คุณมีกับ SublimeText ที่ให้สีที่ดีคืออะไร หรือมันแค่เปลี่ยนสีของหน้าต่าง?
pal4life

1
@ pal4life: มันเรียกsolarized (แสง) ฉันคิดว่า Sublime Text มาพร้อมกับมันด้วย ฉันอาจติดตั้งทางเลือกอื่นแม้ว่าดังนั้นสีอาจไม่ตรงกันทั้งหมด ภาพหน้าจออยู่บน OS X ดังนั้นนั่นคือที่ขอบหน้าต่างและแถบชื่อเรื่องมาจาก
Daniel Beck

83

นอกจากนี้ยังมีอัลกอริทึมการกรองบรรทัดของชายยากจน (หรือขี้เกียจ?):

  1. เลือกสตริงที่สนใจ
  2. กดปุ่มAlt+ F3เพื่อเข้าสู่โหมดมัลติเคอร์เซอร์ในทุกเหตุการณ์
  3. กดControl+ Lเพื่อเลือกทั้งบรรทัด (ในทุกเคอร์เซอร์บรรทัด)
  4. คัดลอกและวางส่วนที่เลือกไปยังบัฟเฟอร์อื่น

2
นี่เป็นทางออกที่ง่ายที่สุด ไชโย!
gillytech

ขอขอบคุณ! ฉันไม่ต้องการติดตั้ง / เรียนรู้ปลั๊กอินอื่นให้มากที่สุดเท่าที่จะเป็นไปได้ - Alt + F3 อยู่ในหน่วยความจำกล้ามเนื้อของฉันดังนั้นวิธีการแก้ปัญหาข้างต้นนั้นไม่ได้ดึงมาให้ฉัน
Olof Bjarnason

คุณสามารถแทนที่ขั้นตอนที่ 3 และ 4 ด้วยขั้นตอนเดียว: Ctrl + L
Andres Riofrio

1
ทางออกที่ดีง่าย! ฉันจะแทนที่ขั้นตอนที่ 3 จาก Ctrl-L เป็น Home, Shift-End ดังนั้นจึงไม่มีบรรทัดว่างระหว่างการเกิดขึ้น
jslap

4
สิ่งนี้เปลี่ยนชีวิตของฉันให้ดีขึ้น จะไม่มีอะไรเหมือนเดิมอีกเลย
Shawson

49

ตอนนี้มีปลั๊กอินสำหรับการกรองบรรทัด: https://github.com/davidpeckham/FilterLines
มันช่วยให้การกรองและการพับโค้ดขึ้นอยู่กับสตริงหรือนิพจน์ทั่วไป


ปลั๊กอินตัวกรองข้อความประเสริฐโดย David Peckham


4
เพิ่งติดตั้งปลั๊กอินนี้ - สมบูรณ์แบบสำหรับงาน ใช้ไฟล์ที่มีอยู่ให้คุณป้อนวลีตัวกรองและวางผลลัพธ์ในแท็บใหม่
Nick

4
เห็นด้วยจนถึงตอนนี้ฉันเพิ่งฝันว่าจะมีฟังก์ชั่นประเภทนี้ในโปรแกรมแก้ไขข้อความของฉัน
Michael12345

1
ปลั๊กอินนี้ยอดเยี่ยมจริงๆ!
Devid

มาที่นี่เพราะผู้ร่วมงานพูดถึงบางสิ่งเกี่ยวกับ "Keep Lines" สำหรับ emacs และมีประโยชน์อย่างไร ไม่รู้ด้วยซ้ำว่าฉันต้องการปลั๊กอินนี้รักมันอย่างแน่นอน!
brandon927

14

คุณสามารถใช้ความสามารถในตัวของ Sublime เพื่อทำสิ่งนี้ในการกดปุ่ม 3 ถึง 7 ครั้ง (ไม่รวม regex ที่จะจับคู่)

ขั้นตอนที่ 1: เลือกหลายบรรทัดที่ตรงกันทั้งหมด

ตัวเลือก 1: การเลือกหลายบรรทัดทั้งหมดที่มีซับสตริง

  1. เลือกสตริงที่สนใจ
  2. กดAlt+ F3เพื่อเลือกหลายรายการที่เกิดขึ้นทั้งหมด
  3. กดCtrl+ L(ขยายส่วนที่เลือกไปยังบรรทัด)

ตัวเลือกที่ 2: เพื่อเลือกหลายบรรทัดทั้งหมดที่ตรงกับ regexp

  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

ยอดเยี่ยม แต่มีวิธีลบบรรทัดว่างหลังจากวางหรือไม่
Sergey Senkov

1
@SergeySenkov แน่นอน! (1) กด Ctrl + F เพื่อเปิด Find drawer (2) ตรวจสอบว่าเปิดใช้งานการจับคู่นิพจน์ปกติ (Alt + R เพื่อสลับ) (3) พิมพ์ "\ n \ n +" (ตรงกับบรรทัดใหม่ที่ต่อเนื่องกันสองบรรทัดขึ้นไป) (4) กด Alt + Enter เพื่อเลือกทุกการแข่งขัน (5) กด Enter เพื่อแทนที่การแข่งขันทั้งหมดด้วยการขึ้นบรรทัดใหม่เดียว
Andres Riofrio
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.