คำสั่ง Linux shell เพื่อกรองไฟล์ข้อความตามความยาวบรรทัด


19

ฉันมีดิสก์อิมเมจ 30gb ของพาร์ติชัน borked (คิดว่าdd if=/dev/sda1 of=diskimage) ที่ฉันต้องการกู้คืนไฟล์ข้อความบางไฟล์ ข้อมูลการแกะสลักเครื่องมือเช่นการทำงานเฉพาะในไฟล์ที่มีส่วนหัวที่กำหนดไว้อย่างดีเช่นไม่ไฟล์ข้อความธรรมดาดังนั้นฉันได้กลับลดลงในเพื่อนที่ดีของฉันforemoststrings

strings diskimage > diskstrings.txt ผลิตไฟล์ข้อความ 3gb ที่มีสตริงจำนวนมากซึ่งส่วนใหญ่เป็นสิ่งที่ไร้ประโยชน์ผสมกับข้อความที่ฉันต้องการจริง ๆ

เรือลาดตระเวนส่วนใหญ่มีแนวโน้มที่จะยาวและไม่มีเรี่ยวแรงมากนัก สิ่งที่ฉันสนใจรับประกันได้ว่าจะน้อยกว่า 16kb ดังนั้นฉันจะกรองไฟล์ตามความยาวบรรทัด นี่คือสคริปต์ Python ที่ฉันใช้:

infile  = open ("infile.txt" ,"r");
outfile = open ("outfile.txt","w");
for line in infile:
    if len(line) < 16384:
        outfile.write(line)
infile.close()
outfile.close()

งานนี้ แต่สำหรับการอ้างอิงในอนาคตจะมีผู้ใดมนต์ขลังหนึ่งบรรทัด (คิดว่าawk, sed) ที่จะกรองไฟล์โดยความยาวสายหรือไม่?

คำตอบ:


28
awk '{ if (length($0) < 16384) print }' yourfile >your_output_file.txt

จะพิมพ์บรรทัดที่สั้นกว่า 16 กิโลไบต์ในตัวอย่างของคุณเอง

หรือถ้าคุณชอบ Perl:

perl -nle 'if (length($_) < 16384) { print }' yourfile >your_output_file.txt

นั่นเป็นเรื่องง่ายที่น่าอาย ขอขอบคุณ. :)
Li-aung Yip

เพิ่มรุ่น Perl แล้วยัง :-)
Janne Pikkarainen

และสคริปต์ awk สามารถเขียนได้เช่นawk 'length($0) < 16384' file > outputเดียวกับการกระทำเริ่มต้นคือการพิมพ์บรรทัด
เกล็

8

นี่คล้ายกับคำตอบของ Ansgar แต่เร็วกว่าเล็กน้อยในการทดสอบของฉัน:

awk 'length($0) < 16384' infile >outfile

มันเป็นความเร็วเดียวกับคำตอบ awk อื่น ๆ มันขึ้นอยู่กับนัยprintของการแสดงออกที่แท้จริง แต่ไม่จำเป็นต้องใช้เวลาในการแบ่งบรรทัดตามที่ Ansgar ทำ

โปรดทราบว่า AWK ให้คุณifฟรี คำสั่งข้างต้นเทียบเท่ากับ:

awk 'length($0) < 16384 {print}' infile >outfile

ไม่มีคำอธิบายif(หรือวงเล็บปีกกาที่ล้อมรอบ) ที่ชัดเจนในคำตอบอื่น ๆ

นี่คือวิธีที่จะทำในsed:

sed '/.\{16384\}/d' infile >outfile

หรือ:

sed -r '/.{16384}/d' infile >outfile

ซึ่งจะลบบรรทัดใด ๆ ที่มีอักขระ 16384 (ขึ้นไป)

เพื่อความสมบูรณ์นี่คือวิธีที่คุณใช้sedในการบันทึกบรรทัดที่ยาวกว่าขีด จำกัด ของคุณ:

sed '/^.\{0,16383\}$/d' infile >outfile

2

คุณสามารถawkเช่น:

$ awk '{ if (length($0) < 16384) { print } }' /path/to/text/file

สิ่งนี้จะพิมพ์บรรทัดที่มีความยาวน้อยกว่า 16K อักขระ (16 * 1024)

คุณสามารถใช้grep:

$ grep ".\{,16384\}" /path/to/text/file

วิธีนี้จะพิมพ์บรรทัดที่มีอักขระสูงสุด 16K ตัว


ไม่แน่ใจว่าgrepเป็นความคิดที่ดีเช่น - มันเป็น regexp ง่ายเพื่อให้แน่ใจว่า awkแต่มีราคาแพงกว่าคอมพิวเตอร์ "ชายที่มีปัญหากล่าวว่า" ฉันจะใช้การแสดงออกปกติ! "ตอนนี้เขามีสองปัญหา" ;)
Li-aung Yip

มันเป็นอีกวิธีหนึ่งในการทำมัน ตัวเลือกแรกที่ฉันโพสต์ใช้awkอยู่
เลด

1
+1 สำหรับ regexp เพราะมันดีกว่ากอล์ฟและมันไม่ทำให้ฉันอ่าน awk manpages =)
Ciro Santilli 新疆改造新疆中心法轮功六四事件

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