วิธีรับสตริงที่สั้นที่สุดในไฟล์ข้อความที่มีเชลล์


3

สมมติว่าฉันมีไฟล์ข้อความด้านล่าง

abcd
aaaaaaa
gfgk
hahahahahahhahh
gf

แล้วก็ gf จะกลับมาความคิดที่ดีใด ๆ

คำตอบ:


7

สมมติว่าบรรทัดของคุณมีตัวอักษร 'word'
และเราไม่คิดว่าการปล่อยให้เชลล์ทำงานได้อีกเล็กน้อย
นี่คือโซลูชัน AWK

# Let your text be in `str.txt`

awk '{print length($1), $1}' str.txt | sort -nk 1 | head -1

# Output: 2 gf ## Which is the shortest string

คุณสามารถปรับให้เหมาะสมเพื่อหลีกเลี่ยงการเรียงลำดับด้วย AWK เพิ่มเติม
คุณสามารถปรับแต่งสิ่งนี้เพิ่มเติมหากคุณมี 'คำ' มากกว่าหนึ่งคำต่อบรรทัด

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


ฉันชอบสิ่งนี้ แต่ควรใช้ $0 (เต็มบรรทัด) แทน $1 (ฟิลด์แรก) $1 จะกลับไปที่ช่องว่างแรกเท่านั้น ตัวอย่างของ SpawnST ไม่มีช่องว่างใด ๆ ดังนั้นจะสามารถใช้งานได้หากไฟล์ข้อมูลจริงของเขาเหมือนกัน
Doug Harris

@ ดั๊กฉันหมายถึงคุณเปิดประโยคของคำตอบ :-)
nik

โอ๊ะขอโทษฉันพลาดสายการสันนิษฐานของคุณไป ฉันได้รับคำตอบให้คุณแล้ว
Doug Harris

10

Awk ยอดเยี่ยมสำหรับสิ่งนี้:

awk '(NR == 1 || length < length(shortest)) { shortest = $0 } END { print shortest }'

ส่วนแรกตั้งค่าตัวแปร "shortest" เป็นบรรทัดปัจจุบันหากเป็นบรรทัดแรกหรือหากความยาวสั้นกว่าบรรทัดที่สั้นที่สุดที่เห็นก่อนหน้านี้ ในที่สุดส่วนสุดท้ายพิมพ์ค่าที่สั้นที่สุด


ดีเลิศเพิ่มไปยังกล่องเครื่องมือ
l0b0

3

ทุบตีคำถามที่พบบ่อย รายการ # 1 บอกวิธีการอ่านไฟล์ทีละบรรทัด ${#foo} จะให้ความยาวของ $foo. เพียงแค่วนรอบทดสอบแต่ละบรรทัดในทางกลับกัน


2

วิธีแก้ปัญหาโดยใช้ sed และป้องกันบรรทัดที่สั้นที่สุดที่ 1 จากไฟล์:

sed -e '1h;H;g;s/[^\n]/#/g;s/\(#*\)\n\1/\n/;G;/^\n/s/\n.*\n\(.*\)\n.*/\1/;s/.*\n//;h;$!d' your_file

หากต้องการเก็บบรรทัดที่สั้นที่สุดจากไฟล์:

sed -e '1h;G;h;s/[^\n]/#/g;s/\(#*\)\n\1/\n/;G;/^\n/s/\n.*\n\(.*\)\n.*/\1/;s/.*\n//;h;$!d' your_file

ร้องเป็นรุ่นที่อธิบายของบรรทัดที่สั้นที่สุดที่ 1 ในรูปแบบของไฟล์สคริปต์ที่สามารถเรียกใช้โดยใช้ sed -f script your_file:

# The hold space will contain the shortest line at the beginning and the ending of each cycle.
# The 1st line is the shortest, so put it in the hold space so an empty line will not be returned.
1h
# Append the current line to the shortest so far, remember these 2 lines in the hold space, and take a copy in the pattern space to work on them.
H;g
# Replace all chars by #.
s/[^\n]/#/g
# Delete the same number of # before and after the line delimiter.
s/\(#*\)\n\1/\n/
# Append the 2 lines remembered in the hold space to the pattern space.
G
# If the hold space begin by a '\n', the current line was shorter, so keep it.
/^\n/s/\n.*\n\(.*\)\n.*/\1/
# Else, the previous line was shorter, so keep it.
s/.*\n//
# Remember shortest in hold space.
h
# If last line, print it (delete everything else).
$!d

+1 สำหรับถ้าคุณดูอย่างใกล้ชิดและนานพอที่สคริปต์บทนี้คุณจะเห็นผู้หญิงในชุดสีแดง ...
michael

0

นี่คือข้อเสนอที่ค่อนข้างงุ่มง่ามของฉันโดยใช้ Perl:

grep . file | perl -E '@a=<>; @s = sort {length $a <=> length $b}@a; say $s[0] . "Line $."; '

ค่อนข้างง่ายกว่า: perl -ne '$ l = $ _ ถ้า $ == 1; $ l = $ _ ถ้ายาว ($ ) & lt; ความยาว ($ ลิตร); END {พิมพ์ $ l;} 'ไฟล์ ### ที่สั้นที่สุด perl -ne '$ l = $ ถ้า $ == 1; $ l = $ _ ถ้า length ($ _) & gt; ความยาว ($ ลิตร); END {พิมพ์ $ l;} 'ไฟล์ ### ยาวที่สุด

grep ไฟล์ | perl -ne '$ l = $ _ ถ้า $ == 1; $ l = $ _ ถ้า length ($ _) & lt; ความยาว ($ ลิตร); END {พิมพ์ $ l;} '## การลบบรรทัดว่างที่สั้นที่สุดที่เป็นไปได้

grep ไฟล์ | perl -ne '$ l = $ _ ถ้า $ == 1; $ l = $ _ ถ้า length ($ _) & lt; ความยาว ($ ลิตร); END {พิมพ์ $ l;} '## การลบบรรทัดว่างที่ยาวที่สุด

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