วิธีลบบรรทัดถ้ายาวกว่า XY


21

ฉันจะลบบรรทัดได้อย่างไรถ้ามันยาวกว่าเช่น: 2048 chars?


คุณยืนยันในการใช้ sed หรือไม่? นี่เป็นเรื่องง่ายเช่นในไพ ธ อน และไม่ต้องสงสัยเลยแม้แต่น้อยใน perl แม้ว่าคำถามจะไม่ได้กำหนดไว้อย่างดีมาก คัดลอกไฟล์ลบทุกบรรทัดที่ยาวกว่า 2048 หรืออย่างอื่นใช่ไหม
Faheem Mitha

คำตอบ:


22
sed '/^.\{2048\}./d' input.txt > output.txt

3
ฉันได้รับข้อความแสดงข้อผิดพลาดsed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s)(Mac OS X)
พุธที่

1
@wedi คุณอาจต้องการติดตั้งรุ่น GNU แทนรุ่น BSD ที่มาพร้อมกับ Mac นี่เป็นเรื่องง่ายด้วยการชง
Freedom_Ben

คำถามบอกว่า "ถ้านานกว่า XY (เช่น 2048 ตัวอักษร)" จากนั้นจะต้องเป็น> 2048 และไม่ใช่ => 2048
ajcg

1
@ajcg คือ> 2048 โปรดสังเกตว่ามีช่วงเวลาพิเศษในตอนท้ายของ regex เพื่อให้ตรงกับอักขระ 2049
forcefsck

@forcefsck และมันจะไม่ดีขึ้นถ้าคุณนำมันออกไป "^"? (ที่มีคำสั่งของคุณคุณเป็นเพียงการลบเส้นที่ "เริ่มต้นด้วย XYZ" แต่ถ้า XYZ อยู่ในส่วนหนึ่งของสายอีกแล้วมันไม่ลบ)
ajcg

7

ต่อไปนี้เป็นโซลูชันที่ลบบรรทัดที่มี 2049 อักขระขึ้นไป:

sed -E '/.{2049}/d' <file.in >file.out

นิพจน์/.{2049}/dจะจับคู่บรรทัดใด ๆ ที่มีอักขระอย่างน้อย 2049 ตัวและลบออกจากอินพุตเพื่อสร้างบรรทัดที่สั้นกว่าในเอาต์พุตเท่านั้น

ด้วยawkการพิมพ์บรรทัดที่มีความยาว 2048 หรือสั้นกว่า:

awk 'length <= 2048' <file.in >file.out

การเลียนแบบsedโซลูชันอย่างแท้จริงด้วยawk:

awk 'length >= 2049 { next } { print }' <file.in >file.out

1
ฉันได้รับข้อความแสดงข้อผิดพลาดsed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s)(Mac OS X)
พุธที่

1
@wedi อัปเดตและทดสอบบน macOS Mojave แล้ว
Kusalananda

2

สิ่งนี้จะทำงานใน Python

of = open("orig")
nf = open("new",'w')
for line in of:         
    if len(line) < 2048:
        nf.write(line)
of.close()
nf.close()

1
โดยส่วนตัว @Faheem ฉันชอบคำตอบของคุณ เหตุผลก็คือมันง่ายมากสำหรับฉันที่จะทำให้มันกลายเป็น 'ลบทุกบรรทัดที่เล็กกว่า x' ฉันไม่ได้ใช้ Python ตลอดเวลา แต่เมื่อฉันทำฉันมักจะรู้สึกว่าฉันควรเรียนรู้ได้ดี
ixtmixilix

@ixtmixilix: ใช่การใช้ภาษาที่มีคุณลักษณะครบถ้วนเช่น Python นั้นค่อนข้างยืดหยุ่น ขอบคุณสำหรับความคิดเห็น
Faheem Mitha

2
perl -lne "length < 2048 && print" infile > outfile

+1 -lไม่จำเป็นต้องทำ
โจเซฟอาร์

ใช้งานไม่ได้สำหรับฉัน Perl v5.16.2 Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1.
พุธที่

length($_) > 2048 && printคุณอาจลอง lengthเป็นทางลัดสำหรับlength($_)ต่อไป
MaratC

0

คำตอบข้างต้นไม่ได้ผลสำหรับฉันบน Mac OS X 10.9.5

รหัสต่อไปนี้ใช้งานได้:

sed '/.\{2048\}/d'.

แม้ว่าจะไม่ได้ถาม แต่มีไว้สำหรับการอ้างอิงกลับสามารถทำได้รหัสต่อไปนี้:

sed '/.\{2048\}/!d'.


lol แต่sed: 1: "/.\{2048\}/d": RE error: invalid repetition count(s)( Mac OS X, 10.10.4)
alex grey

อา ฉันติดตั้งรุ่น GNU แทนรุ่น BSD ที่มาพร้อมกับ Mac ตามที่ @Freedom_Ben แนะนำไว้ข้างต้น แต่ Kusalananda พบสวิตช์เพื่อเปิดใช้งาน regex แบบขยาย ดังนั้นคุณควรไปกับวิธีแก้ปัญหาของเขาหากคุณยังมีปัญหานั้นอยู่ ;)
WEDI

0

ด้วย gnu-sed คุณสามารถใช้แฟล็ก -r เพื่อหลีกเลี่ยงการพิมพ์แบ็กสแลชและเครื่องหมายจุลภาคเพื่อกำหนดช่วงเวลาเปิด:

sed -r  "/.{2049,}/d" input.txt > output.txt

ด้วย:

  • x {2049} หมายถึง 2049 xs
  • x {2049,3072} ความหมายจาก 2049 ถึง 3072 xs
  • x {2049,} ความหมายอย่างน้อย 2049 xs
  • x {, 2049} ความหมายไม่เกิน 2049 xs

สำหรับช่วงเวลาเพื่อให้ไม่ตรงกับรูปแบบที่ใหญ่กว่าคุณจะต้องมีจุดยึดสายเช่น

sed -r  "/^.{32,64}$/d" input.txt > output.txt 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.