วิธีแทรกข้อความที่จุดเริ่มต้นของแต่ละย่อหน้าใน bash


2

ฉันมีไฟล์ที่มีหลายย่อหน้าคั่นด้วยบรรทัดว่าง ในทางเทคนิคแล้วพวกเขาไม่ใช่ย่อหน้าเพียงแค่ส่วนของข้อความคั่นด้วยบรรทัดว่าง

ฉันต้องการกำหนดหมายเลขย่อหน้าเพื่อพูดโดยการใส่ตัวเลขในบรรทัดแรกของแต่ละบรรทัดหลังจากบรรทัดว่าง ดังนั้นหากไฟล์ของฉันพูดว่า:

This is text.
This is more text.
Even more text!

This is text in section two.
Some more text.
You get the point...

ฉันต้องการที่จะทำให้มันพูดว่า:

1This is text
this is more text
Even more text!

2This is text in section two.
Some more text.
You get the point...

คำตอบ:


1

ลองสิ่งนี้ด้วยคำสั่ง bash builtin:

#!/bin/bash

l=1                          # paragraph counter
echo -n $l                   # print paragraph counter without new line
while read x; do             # read current line from file, see last line
  if [[ $x == "" ]]; then    # empty line?
    echo                     # print empty line
    read x                   # read next line from file, see last line
    ((l++))                  # increment paragraph counter
    echo -n $l               # print paragraph counter without new line
  fi
  echo "$x"                  # print current line
done < file

เยี่ยมมาก! ฉันไม่เคยเข้าใกล้มันอย่างนั้น ทำงานได้สมบูรณ์แบบขอบคุณ
OB7

1

โดยทั่วไปการใช้เชลล์สำหรับการแยกวิเคราะห์ข้อความช้ามากและยุ่งยาก นี่คือตัวเลือกอื่น ๆ :

  1. Perl ใน "โหมดย่อหน้า"

    perl -00pe 's/^/$./' file 
    

    คำอธิบาย

    -00 เปิดโหมดย่อหน้าที่ "บรรทัด" ถูกกำหนดโดยต่อเนื่อง \n\nย่อหน้าในคำอื่น ๆ s/^/$./ จะแทนที่จุดเริ่มต้นของบรรทัด ( ^ ) ด้วยหมายเลข "บรรทัด" (ย่อหน้า) ปัจจุบัน $.. -p บอก perl ให้พิมพ์แต่ละบรรทัดของไฟล์อินพุตหลังจากรันสคริปต์ที่กำหนดโดย -e บนมัน

  2. awk

    awk -vRS='\n\n' -vORS='\n\n' '{print NR$0}' file
    

    คำอธิบาย

    -vRS='\n\n' ตั้งค่าตัวคั่นเร็กคอร์ดของ awk เป็นอักขระขึ้นบรรทัดใหม่ต่อเนื่อง เช่นเดียวกับโหมดย่อหน้าของ perl สิ่งนี้ทำให้ถือว่าย่อหน้าเป็น "บรรทัด" จากนั้นเราจะบอกให้พิมพ์หมายเลขบรรทัดปัจจุบัน ( NR ) และ "บรรทัด" ปัจจุบัน $0. -vORS= ตั้งค่าตัวคั่นเร็กคอร์ดเอาต์พุตเป็นบรรทัดใหม่ต่อเนื่องเพื่อให้ย่อหน้าถูกคั่นด้วยบรรทัดว่างในเอาต์พุตเช่นกัน โปรดทราบว่าสิ่งนี้จะเพิ่ม 2 บรรทัดว่างในตอนท้ายของผลลัพธ์ เพื่อหลีกเลี่ยงปัญหานี้คุณสามารถใช้ head:

    awk -v RS='\n\n' -vORS='\n\n' '{print NR$0}' file | head -n -2
    

โดยวิธีการเปรียบเทียบนี่เป็นเวลาที่โซลูชันต่างๆใช้ในระบบของฉันเมื่อทำงานกับไฟล์ทดสอบ 10M

$ time a.sh > /dev/null ## a.sh is Cyrus's solution

real    0m1.419s
user    0m1.308s
sys     0m0.104s

$ time perl -00pe 's/^/$./' file  > /dev/null 

real    0m0.087s
user    0m0.084s
sys     0m0.000s

$ time awk -v RS='\n\n' -vORS='\n\n' '{print NR$0}' file | head -n -2 >/dev/null

real    0m0.074s
user    0m0.056s
sys     0m0.020s

อย่างที่คุณเห็นด้านบนทั้ง perl และ awk solution เป็นลำดับของขนาดที่เร็วกว่าวิธีของเชลล์

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