วิธีรับบรรทัดที่ยาวที่สุดจากไฟล์


10

ฉันสนใจที่จะหาหมายเลขบรรทัดของบรรทัดที่ยาวที่สุดจากไฟล์

ตัวอย่างเช่นถ้าฉันมีไฟล์ที่มีเนื้อหาต่อไปนี้:

lalala
tatatata
abracadabra
mu mu mu

ฉันจะเขียนสคริปต์ทุบตีที่จะให้ผลลัพธ์เช่นนี้ได้3 -> abracadabraอย่างไร:

คำตอบ:


9

คุณไม่จำเป็นต้องมีสคริปต์ในการทำสิ่งนี้ คำสั่งง่าย ๆ ก็เพียงพอแล้ว:

egrep -n "^.{$(wc -L < filename)}$" filename

สิ่งนี้จะทำงานแม้ว่าคุณจะมีสองบรรทัดขึ้นไปที่มีความยาวสูงสุดเท่ากัน

หากคุณต้องการให้ผลลัพธ์เป็นแบบตรง: 3 -> abracadabraให้ใช้:

egrep -n "^.{$(wc -L < filename)}$" filename | sed 's/:/ -> /'

อ้างอิง:


3
@ don.joey: นั่นคือพลังของยูนิกซ์ คำสั่งง่ายๆที่สามารถทำงานร่วมกันได้ ที่นี่เขามองหา "^. {n} $" นั่นคือบรรทัดใด ๆ ระหว่างจุดเริ่มต้นของบรรทัด ( ^) และจุดสิ้นสุด ( $) มีอักขระทั้งหมด n ตัว ( .{n}) จากนั้นเขาเพียงต้องการค้นหา n: สำหรับสิ่งนี้เขาใช้ GNU-ism "wc -L filename" (โปรดทราบว่านี่ไม่ใช่ posix) ซึ่งคืนความยาวของชื่อไฟล์ที่ยาวที่สุด ดังนั้นเขาจึง greps บรรทัดใด ๆ ที่มีความยาวที่ยาวที่สุด จะถูกแทนที่ด้วยการส่งออกของ$(cmd) cmd
Olivier Dulac

1
@OlivierDulac ความคิดเห็นที่ดี
Radu Rădeanu

ยิ่งไปกว่านั้นคุณยังสามารถเพิ่ม (เช่น) -C 3ไปยังตัวเลือก grep เพื่อรับบรรทัดก่อนและหลังสำหรับบริบท
ShadSterling

8

คุณสามารถใช้awkพิมพ์ความยาวของแต่ละบรรทัด ( length()) และหมายเลขบรรทัด ( NR) จากนั้นย้อนกลับ ( -r) sortผลลัพธ์ตามหมายเลข ( -n):

$ awk '{ print length(), NR, $0 | "sort -rn" }' tmp.txt
10 3 abracadabr
8 4 mu mu mu
7 2 tatatat
6 1 lalala

หากต้องการแสดงเพียงบรรทัดแรก:

$ awk '{ print length(), NR, $0 | "sort -rn" }' tmp.txt | head -n 1
10 3 abracadabr

@ user214965 โปรดดูการอัพเดตของฉันหมายเลขบรรทัดที่แสดงเป็นหมายเลขที่สองในผลลัพธ์
อัตติลาทุม

เกิดอะไรขึ้นถ้ามี 2 บรรทัดที่มีความยาวสูงสุดเท่ากัน?
Radu Rădeanu

@ RaduRădeanuจุดที่ดี +1 สำหรับwc -Lฉันไม่ทราบเกี่ยวกับข้อโต้แย้งนั้น มันมีประโยชน์มากอย่างแน่นอน
อัตติลาทุม

4

AO (N) สามารถทำได้ด้วย perl one liner:

perl -e 'while (<>) { if (length > length $max) { $max=$_}}; print $max'

ประเพณี (โดยที่ machin เป็นชื่อไฟล์)

cat machin | perl -e 'while (<>) { if (length > length $max) { $max=$_}}; print $max'

หรือ

perl -e 'while (<>) { if (length > length $max) { $max=$_}}; print $max' machin

หรือ (ชัดเจนน้อยลง แต่สั้นลง)

perl -ne 'if(length>length$m){$m=$_};END{print$m}' machin

มีประสิทธิภาพมากขึ้น ขอบคุณ! กำลังมองหามัน
ทดสอบ 30

1
ใช้ได้กับไฟล์ขนาดใหญ่ +1
h3xStream

0

O (n) สำหรับเครื่องจักรเช่น OpenWRT ที่ไม่สามารถใช้ perl ได้ @ awk @ version อาจมีประโยชน์

awk 'length > l {l=length;line=$0} END {print line}' FILE

หรือหลาม:

python -c "print max(open('$file', 'r'), key=len)"

0

คำตอบของ Radu นั้นเพียงพอและต้องการอย่างสมบูรณ์แม้ว่าคุณต้องการโซลูชันที่ชัดเจนและใช้เชลล์มากขึ้นคุณก็สามารถใช้สคริปต์ต่อไปนี้:

#!/bin/bash
longest_length=0
longest_string=0
while IFS= read -r line || [ -n "${line}"]
do
    if [ "${#line}" -gt "${longest_length}" ]
    then
        longest_length="${#line}"
        longest_string="$line"
    fi
done < "$1"

echo "${longest_string}"

การใช้งาน: ./find_longest.sh input.txt

ตัวอย่าง:

$ cat input.txt                                                          
1 2 
2 3 a a a a
4 5 6 
1 1 1 5

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