จะค้นหาบรรทัดที่ตรงกับรูปแบบและลบได้อย่างไร?


14

HERE IT ISในแฟ้มที่มีจำนวนมากของสายฉันต้องการที่จะลบเส้นที่เริ่มต้นด้วย

ฉันจะทำได้โดยใช้เครื่องมือบรรทัดคำสั่งเท่านั้น


2
แม้ว่าจะไม่เป็นทางการ แต่คุณสามารถใช้vimดังนี้: vim '+g/^HERE IT IS/d' +wq test.txt;)
Doorknob

@ Doorknob ขอบคุณสำหรับการชี้ให้เห็น จริงๆแล้วฉันกำลังใช้ vim
micgeronimo

คำตอบ:


29

ลองsed:

sed -i '/^HERE IT IS/d' <file>

คำเตือน:ควรสำรองข้อมูลเมื่อใช้-iสวิตช์sed:

sed -i.bak '/^HERE IT IS/d' <file>

ไฟล์ต้นฉบับจะยังคงเป็นและแฟ้มที่แก้ไขจะเป็น<file>.bak<file>


ฉันจะใส่อักขระบรรทัดใหม่หลังจากจับคู่สตริงแล้วเขียนไปยังบรรทัดใหม่ได้อย่างไร
micgeronimo

2
sed -i 's/^HERE IT IS/HERE IT IS\n/' <file>
heemayl

1
@micgeronimo: ยินดีที่จะช่วย โปรดตรวจสอบการแก้ไขของฉัน
heemayl

6
@micgeronimo พยายามถามคำถามที่คุณต้องการตอบในคำถามเดิมของคุณ (โปรดจำไว้ว่าคุณสามารถแก้ไขได้) แทนที่จะอ่านความคิดเห็นที่อาจถูกล้าง / ลบ sed '/^HERE IT IS/G' fileคุณสามารถใช้
ขับขี่เหล็ก

1
การใช้งาน Sed เป็นมืออาชีพมาก
LakshyaAg

18

นอกจากสิ่งที่ดีgrepและsedคำตอบที่คุณได้รับแล้วนี่คือเครื่องมืออื่น ๆ ที่สามารถทำสิ่งเดียวกัน:

  • วิธี Perl ไม่กี่:

    perl -ne '/^HERE IT IS/ || print' file > newfile
    perl -ne 'print if !/^HERE IT IS/' file > newfile
    perl -ne 'print unless /^HERE IT IS/' file > newfile
    

    คุณสามารถเพิ่ม-iสวิตช์ลงในตัวอย่างใดก็ได้เพื่อแก้ไขไฟล์:

    perl -i.bak -ne '/^HERE IT IS/ || print' file        
    
  • (ช) awk

    awk '!/^HERE IT IS/' file > newfile
    

    รุ่นที่ใหม่กว่า (4.1.1 ขึ้นไป) ของ GNU awk(ค่าเริ่มต้นawkบน Linux) ยังสามารถแก้ไขไฟล์ได้:

    gawk -i inplace  '!/^HERE IT IS/' file
    
  • Shell ( bash, zsh, kshอาจจะเป็นคนอื่น ๆ ) มันค่อนข้างโง่ แต่ก็สามารถทำได้ แต่เครื่องมืออื่น ๆ ดีกว่า

    while IFS= read -r line; do 
      [[ $line =~ ^"HERE IT IS" ]] || printf "%s\n" "$line"
    done < file > newfile
    

1
คุณเพิ่งจะแสดง! ;-) (แต่คุณได้รับการโหวตเพราะมันฉลาดและฉันได้เรียนรู้มากมายและสิ่งbashหนึ่งที่ทำให้ฉัน LOL)
Fabby

คนทุบตีควรใช้printf "%s\n" "$line": อ้างถึง $ line เพื่อรักษาช่องว่างและหลีกเลี่ยงปัญหาเสียงก้อง (ตีความตัวอักษรพิเศษ ฯลฯ ) และหลีกเลี่ยงความจำเป็นที่จะต้องเพิ่ม--ด้วย
Olivier Dulac

@ OlivierDulac ยุติธรรมพอสมควร ฉันไม่ต้องการที่จะทำให้สิ่งต่าง ๆ ยุ่งยากสำหรับกรณีที่ขอบ แต่ตั้งแต่ Cuanglm ได้เพิ่มIFS=และ-rฉันอาจไปตลอดทางและทำให้มันแข็งแกร่ง
terdon

@terdon: มันเป็นสิ่งที่ดีกว่า ^^ (และฉันได้ +1 ไปแล้ว แต่เนื่องจากเป็นข้อมูลที่ดีสำหรับผู้เริ่มต้น)
Olivier Dulac

2
@OlivierDulac ฉันรับรองได้เลยว่าถ้าฉันโพสต์บนUnix & Linuxฉันได้ใช้ printf, IFS =, -r และ quoting :) ฉันมักจะทำให้สิ่งต่าง ๆ ง่ายขึ้นสำหรับผู้ชม AU ที่มักไม่ค่อยสบายใจกับบรรทัดคำสั่ง
terdon


5

sed เป็นวิธีที่จะไปแน่นอน

การแก้ไขเล็กน้อยของคำสั่ง @heemayl นี้ให้คุณจะลบบรรทัดไม่ว่ากรณีเดียวกันจะถูกใช้ในรูปแบบหรือไม่เนื่องจาก I ในการอ้างอิงรูปแบบ

sed -i '/HERE IT IS/Id' <file>

หากคุณมีหลายไฟล์ในไดเรกทอรีที่คุณต้องการทำเช่นนี้คุณสามารถรวมเข้ากับ find เช่น

find . -maxdepth 1 -type f -exec sed -i.bak '/HERE IT IS/Id' {} +

ตัวเลือก maxdepth หมายความว่าสิ่งนี้จะไม่ถูกเก็บในไดเรกทอรี


4

ตัวเลือกหลามอื่น:

#!/usr/bin/env python3
[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]

โดยที่ f คือพา ธ ไปยังไฟล์ระหว่างเครื่องหมายคำพูด


4

grep

grep -P '^(?!HERE IT IS)' file

(?!HERE IT IS)การยืนยันแบบ lookahead เชิงลบซึ่งทำให้เอ็นจิน regex จับคู่กับทุกเส้นเริ่มต้นของขอบเขต ( ซึ่งมักจะถูกจับคู่ด้วย^ ) เฉพาะในกรณีที่มันไม่ได้ตามด้วยสตริงHERE IT IS

หลาม

#!/usr/bin/python3
import sys
fil = sys.argv[1]
with open(fil) as f:
    for line in f:
        if not line.startswith('HERE IT IS'):
            print(line, end="")

บันทึกสคริปต์ในไฟล์พูดscript.pyแล้วเรียกใช้คำสั่งด้านล่างบนเทอร์มินัล

python3 script.py infile

คุณสามารถใช้ regex มีเช่นแต่ก็ไม่ได้มีประสิทธิภาพมากขึ้นกว่า[print(l, end = "") for l in open(fil).readlines() if not re.match("HERE IT IS", l)] startswithฉันสงสัยว่า[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]จะไม่สร้างผลลัพธ์ในรายการได้อย่างไร
Avinash Raj

ครั้งแรกที่ฉันพบมันมันดูแปลกสำหรับฉัน มันสร้างคำสั่งพิมพ์ (หรือสิ่งที่คุณต้องการด้วย) สำหรับทุกรายการในรายการที่กำหนด
Jacob Vlijm

การยกเลิกการลบมันเพียงเพื่อความสนุกสนาน :)
จาค็อบ Vlijm

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.