tr -c \\n 1 <testfile | #first transform every [^\n] char to a 1
grep -nF '' | #next get line numbers
paste -d: - testfile | #then paste it together with itself
sort -t: -nk2,2 #then sort on second field
... และผู้ชนะคือ ... บรรทัดที่ 2 มันจะดูเหมือน
2:1111:4for
4:11111:five!
1:1111111:seven/7
3:11111111:8 eight?
แต่ปัญหาที่เกิดขึ้นก็คือทุกบรรทัดต้องมีความยาวมากกว่าสองเท่าเพื่อให้มันทำงานได้ดังนั้นLINE_MAXจึงลดลงครึ่งหนึ่งอย่างมีประสิทธิภาพ สาเหตุก็คือมันใช้งานอยู่ - อะไรคือฐาน 1? - เพื่อแสดงความยาวของเส้น แนวทางที่คล้ายกันและเป็นระเบียบมากขึ้นอาจบีบอัดข้อมูลนั้นในสตรีม ความคิดแรกตามแนวที่เกิดขึ้นกับฉันคือฉันควรจะunexpand
:
tr -c \\n \ <testfile | #transform all [^\n] to <space>
unexpand -t10 | #squeeze every series of 10 to one tab
grep -nF '' | #and get the line numbers
sed 's/:/!d;=;:/;h;:big #sed compares sequential lines
$P;$!N; /\(:[^ ]*\)\( *\)\n.*\1.*\2/!D #newest line is shorter or...
g;/:./!q;b big' | #not; quit input entirely for blank line
sed -f - -e q testfile #print only first occurrence of shortest line
พิมพ์ออกมา ...
2
4for
อีกหนึ่งเพียงsed
:
sed -n '/^\n/D;s/\(.\)\(\n.*\)*/\1/g
$p;h; s// /g;G;x;n;//!g;H;s// /g
G; s/^\( *\)\(\n \1 *\)\{0,1\}\n//
D' <infile >outfile
ไวยากรณ์เป็นไปตามมาตรฐาน - แต่นั่นไม่รับประกันว่าsed
จะมีคนเก่าจัดการ\(reference-group\)\{counts\}
อย่างถูกต้อง - หลายคนไม่ได้
โดยทั่วไปแล้วจะใช้ regexp เดียวกันกับการป้อนข้อมูลซ้ำ ๆ - ซึ่งจะเป็นประโยชน์มากเมื่อถึงเวลาที่จะรวบรวมพวกเขา รูปแบบนั้นคือ:
\(.\)\(\n.*\)*
ซึ่งจับคู่สตริงที่แตกต่างกันในวิธีต่างๆ ตัวอย่างเช่น:
string1\nstring2\nstring3
... จะถูกจับคู่กับs
ใน\1
และสตริงใน''
\2
1\nstring2\nstring3
... ถูกจับคู่กับ1
ใน\1
และ\nstring2\nstring3
ใน\2
\nstring2\nstring3
... จะถูกจับคู่กับ\n
ใน\1
และสตริงใน''
\2
นี่จะเป็นปัญหาหากมีโอกาสที่\n
ewline เกิดขึ้นที่ส่วนหัวของพื้นที่รูปแบบ - แต่ใช้คำสั่ง/^\n/D
และและ//!g
เพื่อป้องกันสิ่งนี้ ฉันใช้ไปแล้ว[^\n]
แต่ความต้องการอื่น ๆ สำหรับสคริปต์ตัวเล็กนี้ทำให้การพกพาเป็นเรื่องที่น่ากังวลและฉันก็ไม่พอใจกับหลาย ๆ วิธีที่มักถูกตีความผิด บวก.
เร็วกว่า
\nstring2
string1
... จับคู่\n
และs
อีกครั้ง\1
ทั้งคู่รับ''
ค่าสตริง\2
ว่าง บรรทัดว่างไม่ตรงกันเลย
เมื่อรูปแบบจะถูกนำไปใช้g
loballyสองอคติ - ทั้งอคติซ้ายสุดมาตรฐานและเลสเบี้ยนด้านขวา\n
ewline อคติ - มีการทวนความสมดุลจะทำให้เกิดการข้าม ตัวอย่างบางส่วน:
s/\(.\)\(\n.*\)*/\1:\2/g
s/\(.\)\(\n.*\)*/\2\1:/g
s/\(.\)\(\n.*\)*/\1: /g
s/\(.\)\(\n.*\)*/ :\2/g
... ถ้าใช้ทั้งหมด(ไม่ต่อเนื่อง)กับสตริงต่อไปนี้ ...
string1\nstring2
... จะแปลงเป็น ...
s:t:r:i:n:g:1:\nstring2
s:t:r:i:n:g:\nstring21:
s:t:r:i:n:g:1:
: : : : : : :\nstring2
โดยทั่วไปฉันใช้ regexp เพื่อจัดการเฉพาะบรรทัดแรกในพื้นที่รูปแบบใด ๆ ที่ฉันใช้มัน ที่ช่วยให้ฉันสามารถเล่นสองรุ่นที่แตกต่างกันของทั้งคู่ที่สั้นที่สุดจับคู่ไกลและสายล่าสุดโดยไม่ต้องหันไปทดสอบลูป - การทดแทนทุกครั้งที่ใช้จะจัดการกับพื้นที่รูปแบบทั้งหมดในครั้งเดียว
รุ่นที่แตกต่างกันมีความจำเป็นสำหรับการเปรียบเทียบสตริง / สตริงตามตัวอักษร - ดังนั้นจะต้องมีเวอร์ชันของแต่ละบรรทัดที่อักขระทั้งหมดรับประกันว่าจะเท่ากัน แต่แน่นอนถ้าหนึ่งหรืออื่น ๆ ควรจบลงจริง ๆ แล้วเป็นบรรทัดที่สั้นที่สุดที่เกิดขึ้นเร็วที่สุดในบรรทัดแล้วพิมพ์บรรทัดที่ส่งออกไปอาจจะเป็นรุ่นดั้งเดิมของบรรทัด - ไม่ใช่คนที่ฉันได้ sanitized / homogenized เพื่อประโยชน์ของการเปรียบเทียบ ดังนั้นฉันต้องการสองรุ่นแต่ละรุ่น
มันเป็นเรื่องโชคร้ายที่ความจำเป็นอีกอย่างหนึ่งคือการสลับบัฟเฟอร์เพื่อจัดการเหมือนกัน - แต่อย่างน้อยบัฟเฟอร์ไม่เกินเกินกว่าสี่บรรทัดที่จำเป็นในการรักษากระแส - และบางทีมันอาจจะไม่น่ากลัว
อย่างไรก็ตามสำหรับแต่ละรอบสิ่งแรกที่เกิดขึ้นคือการเปลี่ยนแปลงในบรรทัดที่จดจำ - เนื่องจากสำเนาที่บันทึกจริงเท่านั้นคือต้นฉบับดั้งเดิม - เป็น ...
^ \nremembered line$
... และหลังจากนั้นn
บรรทัดอินพุตอินพุตจะเขียนทับบัฟเฟอร์เก่าใด ๆ หากไม่มีอย่างน้อยหนึ่งตัวอักษรก็จะถูกละเว้นอย่างมีประสิทธิภาพ มันจะง่ายกว่าที่จะq
ใช้บรรทัดแรกที่ว่างเปล่า แต่ข้อมูลการทดสอบของฉันมีจำนวนมากและฉันต้องการจัดการหลายย่อหน้า
ดังนั้นถ้ามันมีตัวอักษรเวอร์ชันที่เป็นตัวอักษรจะถูกต่อท้ายบรรทัดที่จดจำและเวอร์ชันเปรียบเทียบที่เว้นระยะจะอยู่ในตำแหน่งที่ส่วนหัวของรูปแบบพื้นที่เช่นนี้:
^ \n \nremembered line\nnew$
การทดแทนครั้งสุดท้ายจะใช้กับพื้นที่รูปแบบนั้น:
s/^\( *\)\(\n \1 *\)\{0,1\}\n//
ดังนั้นหากบรรทัดใหม่สามารถพอดีกับพื้นที่ที่ต้องการเพื่อให้มีบรรทัดที่ถูกจดจำด้วยอักขระอย่างน้อยหนึ่งตัวเพื่อสำรองดังนั้นสองบรรทัดแรกจะถูกแทนที่ออกไปมิฉะนั้นจะเป็นบรรทัดแรกเท่านั้น
บรรทัดแรกในพื้นที่รูปแบบจะถูกD
ลบเมื่อสิ้นสุดรอบการทำงานโดยไม่คำนึงถึงผลลัพธ์ก่อนที่จะเริ่มต้นอีกครั้ง ซึ่งหมายความว่าหากบรรทัดใหม่สั้นกว่าสตริงสุดท้าย ...
new
... ถูกส่งกลับไปที่การทดแทนครั้งแรกในรอบซึ่งจะตัดเฉพาะจากตัวอักษรขึ้นบรรทัดใหม่ตัวแรก - และดังนั้นจึงยังคงอยู่ทั้งหมด แต่ถ้ามันไม่ได้เป็นสตริง ...
remembered line\nnew
... จะเริ่มรอบถัดไปแทนและการแทนที่ครั้งแรกจะตัดจากสตริงนั้น ...
\nnew
...ทุกเวลา.
ในบรรทัดสุดท้ายบรรทัดที่จดจำจะถูกพิมพ์ไปที่มาตรฐานและดังนั้นสำหรับข้อมูลตัวอย่างที่ให้มามันจะพิมพ์:
4for
tr
แต่อย่างจริงจังใช้