รวมหลายบรรทัดแบบไดนามิกในยูนิกซ์


3

ฉันมีสถานการณ์ด้านล่าง:

การวนซ้ำ 1 -

Ddd
Bbb
Ccc
Ddd
Eee
Fff
Ddd

การวนซ้ำ 2 -

Ddd
Bbb
Ddd

ฉันต้องการรวมข้อมูลดังต่อไปนี้ -

วนซ้ำ 1 เอาต์พุต -

Ddd Bbb Ccc
Ddd Eee Fff
Ddd

เอาต์พุต 2 ซ้ำ -

Ddd bbb
Ddd

ฉันต้องการใช้ awk NR เพื่อสร้างไดนามิก chunks เพื่อรวมข้อมูลเช่น NR% 3 ใน Iteration 1 Output และ NR% 2 ใน Iteration 2 Output

ฉันลองใช้ตัวแปรเพื่อกำหนดค่าแบบไดนามิกเช่น NR% $ cnt แต่มันส่งผลให้เกิดข้อผิดพลาด

กรุณาช่วย

คำตอบ:


2

วิธีการของฉันไม่จำเป็นต้องมีข้อสันนิษฐานว่าDddเกิดขึ้นบ่อยแค่ไหน; มันสามารถเกิดขึ้นไม่สม่ำเสมอ วิธีการควรใช้งานได้ยกเว้นว่ามีตัวละครที่ไม่มีค่าในที่ของคุณหรืออินพุตไม่ได้ขึ้นบรรทัดใหม่ (ดูที่นี่ ) หรือเครื่องมือของคุณมีข้อ จำกัด (เช่นsed -zไม่ได้ระบุโดย POSIX)

sed '1! s/^Ddd$/\x00Ddd/' | tr '\n' ' ' | sed -z 's/ $/\n/' | tr -d '\0'

ขั้นตอน:

  1. sedตรวจจับบรรทัดที่อยู่Dddและนำหน้าแต่ละบรรทัดด้วยอักขระ null ยกเว้นว่าบรรทัดนั้นเป็นบรรทัดแรก อักขระ null เหล่านี้แยกบรรทัดของเราเป็น
  2. trแทนที่อักขระขึ้นบรรทัดใหม่ด้วยอักขระเว้นวรรค สิ่งนี้สร้างบรรทัดที่จะเป็นของเรา: บรรทัดก่อนหน้านี้ถูกคั่นด้วยช่องว่าง
  3. แต่ละคน แต่ที่ผ่านมาสายเพื่อจะมีพื้นที่พิเศษในตอนท้ายของการขึ้นบรรทัดใหม่จากเดิมก่อนDdd; บรรทัดสุดท้ายที่จะมีพื้นที่พิเศษจากบรรทัดใหม่สุดท้ายที่ POSIX ต้องการ sed -zอ่านสตริงที่สิ้นสุดด้วย null (lines-to-be) และแทนที่อักขระช่องว่างต่อท้ายด้วยการขึ้นบรรทัดใหม่ตามปกติ ในขณะนี้เส้นที่จะกลายเป็นบรรทัดปกติ
  4. tr -d ลบอักขระ null

1

คุณอาจจะสามารถใช้สิ่งนี้ (มันมาจาก coreutils ของ GNU):

pr --columns=3 --across --separator=' ' --omit-pagination    # pr -3 -a -s' ' -T

มันจะอ่านจากstdinหรือจากไฟล์ ให้คอลัมน์แรกของข้อมูลของคุณผลลัพธ์เป็นดังนี้:

Ddd Bbb Ccc
Ddd Eee Fff
Ddd

เปลี่ยน--columns=3ไป--columns=2สำหรับไฟล์ที่สอง:

Ddd bbb
Ddd

ขอบคุณสำหรับการตอบกลับของคุณ แต่ฉันกำลังมองหาคำสั่งเฉพาะ unix ที่สามารถใช้ในสคริปต์ได้
Tarun Mathur

1
ทำไมคุณไม่คิดว่านี่เป็นคำสั่ง Unix ที่สามารถใช้ในสคริปต์ได้
roaima

1

นี่คือตัวเลือก (มาจาก GNU findutils):

xargs --no-run-if-empty --max-args=3    # xargs -r -n3

มันจะอ่านจากstdinหรือจากไฟล์ ให้คอลัมน์แรกของข้อมูลของคุณผลลัพธ์เป็นดังนี้:

Ddd Bbb Ccc
Ddd Eee Fff
Ddd

เปลี่ยน--max-args=3ไป--max-args=2สำหรับไฟล์ที่สอง:

Ddd bbb
Ddd

awkนี่เป็นอีกทางเลือกหนึ่งในครั้งนี้ขึ้นอยู่รอบ ๆ เปลี่ยนNR % 3ไปNR % 2สำหรับไฟล์ที่สอง

awk '{ printf "%s", $0 } { if (NR % 3) { printf " " } else { printf "\n" } }'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.