สมมติว่าฉันมีไฟล์ข้อความด้านล่าง
abcd
aaaaaaa
gfgk
hahahahahahhahh
gf
แล้วก็ gf
จะกลับมาความคิดที่ดีใด ๆ
สมมติว่าฉันมีไฟล์ข้อความด้านล่าง
abcd
aaaaaaa
gfgk
hahahahahahhahh
gf
แล้วก็ gf
จะกลับมาความคิดที่ดีใด ๆ
คำตอบ:
สมมติว่าบรรทัดของคุณมีตัวอักษร '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 เพิ่มเติม
คุณสามารถปรับแต่งสิ่งนี้เพิ่มเติมหากคุณมี 'คำ' มากกว่าหนึ่งคำต่อบรรทัด
โปรดทราบด้วยว่าหากคุณมีสตริงที่สั้นที่สุดหลายอันสตริงนี้จะให้หนึ่งในนั้น
คุณสามารถทำเทคนิคเพิ่มเติมเพื่อให้ได้เช่นกัน
Awk ยอดเยี่ยมสำหรับสิ่งนี้:
awk '(NR == 1 || length < length(shortest)) { shortest = $0 } END { print shortest }'
ส่วนแรกตั้งค่าตัวแปร "shortest" เป็นบรรทัดปัจจุบันหากเป็นบรรทัดแรกหรือหากความยาวสั้นกว่าบรรทัดที่สั้นที่สุดที่เห็นก่อนหน้านี้ ในที่สุดส่วนสุดท้ายพิมพ์ค่าที่สั้นที่สุด
ทุบตีคำถามที่พบบ่อย รายการ # 1 บอกวิธีการอ่านไฟล์ทีละบรรทัด ${#foo}
จะให้ความยาวของ $foo
. เพียงแค่วนรอบทดสอบแต่ละบรรทัดในทางกลับกัน
วิธีแก้ปัญหาโดยใช้ 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
นี่คือข้อเสนอที่ค่อนข้างงุ่มง่ามของฉันโดยใช้ 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;} '## การลบบรรทัดว่างที่ยาวที่สุด
$0
(เต็มบรรทัด) แทน$1
(ฟิลด์แรก)$1
จะกลับไปที่ช่องว่างแรกเท่านั้น ตัวอย่างของ SpawnST ไม่มีช่องว่างใด ๆ ดังนั้นจะสามารถใช้งานได้หากไฟล์ข้อมูลจริงของเขาเหมือนกัน