ทำซ้ำแต่ละบรรทัดหลายครั้ง


17

ต้องการให้แต่ละบรรทัดในไฟล์ซ้ำกันหลายครั้ง

เช่นให้แต่ละบรรทัดทำซ้ำสี่ครั้ง:

a
b
c

กลายเป็น:

a
a
a
a
b
b
b
b
c
c
c
c

ฉันได้ทำการค้นหาแล้วและมีคำถามและคำตอบมากมายในแนวของการย้อนกลับเช่นการรวมบรรทัดที่ซ้ำกันเป็นบรรทัดเดียว

มันง่ายที่จะทำใน C แต่ฉันหวังว่าฉันจะรู้มากขึ้นเกี่ยวกับคำสั่งดั้งเดิมดังนั้นฉันจึงไม่ต้องหันไปใช้วิธีการโยนครั้งเดียวแบบนี้ตลอดเวลา

คำตอบ:


19
  • Perl:

    perl -ne 'for$i(0..3){print}' file

    และฉันต้องเพิ่มสิ่งนี้โพสต์เป็นความคิดเห็นโดย @derobert เพราะมันเจ๋งมาก:

    perl -ne 'print "$_" x4'
  • awk และตัวแปร:

    awk '{for(i=0;i<4;i++)print}' file
  • bash

    while read line; do for i in {1..4}; do echo "$line"; done; done < file

1
awk's forไม่ต้องการจัดฟันถ้ามีเพียงหนึ่งคำสั่งที่จะทำซ้ำ และperlจะง่ายถ้าคุณใช้ห่วง:foreach for$i(0..3){print}
จัดการ

4
ทางเลือกที่เป็นอันตราย: perl -ne 'print(($_)x4)'. นอกจากนี้คุณควรอ้างอิง$line(เป็น echo) ในเวอร์ชัน bash ของคุณ
Derobert

ในกรณีของฉันฉันต้องการ Windows line-endings เท่าที่เห็นนี่สามารถประสบความสำเร็จกับBEGIN { ORS="\r\n" }
แดงถั่ว

34

ฉันสงสัยว่านี่จะกลายเป็นการแข่งขันกอล์ฟหรือไม่ :

sed 'p;p;p' 
awk '1;1;1;1' 
perl -lpE 'say;say;say'   # if Paul McCartney and Michael Jackson were hackers...

คำอธิบาย:

pคำสั่งของ sed คือการพิมพ์บรรทัดปัจจุบัน พฤติกรรมเริ่มต้นคือการพิมพ์บรรทัดปัจจุบันก่อนที่จะย้ายไปที่บรรทัดถัดไป-nต้องอนุญาตให้คุณปิดการทำงาน) seds รุ่นเก่าบางรุ่นไม่มีเซมิโคลอน (ฉันคิดว่า) ดังนั้นจึงเป็นไปได้ที่คุณอาจต้องทำsed -e p -e p -e p

Awk ทำงานร่วมกับcondition {action}คู่ หากละเว้นการกระทำค่าเริ่มต้นคือพิมพ์บรรทัดปัจจุบันหากเงื่อนไขส่งคืนจริง Awk ก็เหมือนกับภาษา C หลายภาษา1เป็นจริง (เพื่อความสมบูรณ์หากไม่มีการระบุเงื่อนไขการดำเนินการจะถูกดำเนินการสำหรับแต่ละระเบียน)

ฟังก์ชั่น Perl จำนวนมากใช้ประโยชน์จากตัวแปร "default" หนึ่งซับนี้เทียบเท่ากับ (บน perl 5.16):

$ perl -MO=Deparse -lpE 'say;say;say'
BEGIN { $/ = "\n"; $\ = "\n"; }
use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    say $_;
    say $_;
    say $_;
}
continue {
    die "-p destination: $!\n" unless print $_;
}

1
+1 ถ้าใช่คุณชนะ :) สิ่งที่1ต้องทำใน awk คืออะไร? ชวเลขprint $0?
terdon

3
คำสั่ง Awk ประกอบด้วยเงื่อนไขและบล็อกซึ่งเป็นทางเลือก แต่ต้องมีหนึ่งรายการ เงื่อนไขเริ่มต้นคือ1(จริง); {print}บล็อกเริ่มต้นคือเทียบเท่ากับ ดังนั้นคำสั่ง1จะหมายถึงการพิมพ์บรรทัดบัฟเฟอร์ปัจจุบัน ( {print}) ( {print}และ{print $0}ส่วนใหญ่จะเหมือนกัน, qed.)
Arcege

ฉันไม่เคยได้ยินชื่อsedที่ไม่รองรับเครื่องหมายอัฒภาคในฐานะตัวยกเลิกคำสั่ง มีเรื่องแบบนี้จริงเหรอ?
สัญลักษณ์ตัวแทน


4

คุณสามารถทำได้โดยไม่ต้องsed, หรือperlawk

$ for i in `cat <file>` ; do seq <#> <#> | xargs -i -- echo $i ; done

หรือใช้ขณะที่ห่วง:

$ while read i ; do seq <#> <#> | xargs -i -- echo $i ; done < <file>

ตัวอย่าง

สำหรับวง
$ for i in `cat sample.txt` ; do seq 1 3 | xargs -i -- echo $i ; done
a
a
a
b
b
b
c
c
c
ในขณะที่วง
$ while read i; do seq 1 2| xargs -i -- echo $i;done < sample.txt
a
a
b
b
c
c

ฉันคิดว่าเวอร์ชัน for for loop จะหยุดบนบรรทัดใด ๆ ที่มีช่องว่างดังนั้นควรเลือก while loop มิฉะนั้น +1 เนื่องจากฉันเป็นคนที่ชอบอมสำหรับการแก้ปัญหาเชลล์
evilsoup

@evilsoup - ใช่คนอื่นพูดถึงเรื่องนี้เช่นกันในบางรหัสที่ฉันโพสต์ในคำถาม & คำตอบอื่น ฉันคิดว่านั่นเป็นข้อได้เปรียบหลักในขณะที่ในขณะที่ห่วงในขณะที่ทนต่อการแยก $ IFS และจะแยกในตอนท้ายของบรรทัดในขณะที่สำหรับการแยกใน $ IFS
slm

1

ใช้เปลือกหมดจด:

repeats=4
while read line; do yes $line|head --lines=$repeats; done < infile > outfile

มีใครรู้วิธีทำให้ใช่ให้พิจารณา--helpว่าเป็นสตริงแทนที่จะเป็นตัวเลือกหรือไม่? [พิจารณากรณีที่lineมี--helpหรือตัวเลือกอื่น]
176581

ใช่yes -- --help
don_crissti

การใช้yesและheadหมายความว่านี่ไม่ใช่ "เปลือกอย่างหมดจด"
เกล็นแจ็

1

สิ่งนี้อาจใช้ได้กับคุณ (GNU sed):

sed 'h;:a;s/[^\n]\+/&/4;t;G;ba' file

จะทำซ้ำแต่ละบรรทัด 4 ครั้ง

หรือถ้าคุณต้องการ:

sed 'h;:a;s/\n/&/3;t;G;ba' file

ที่คุณทำซ้ำแต่ละบรรทัด 3 ครั้งมากขึ้น


1

@potong คำตอบของไม่ทำงานกับบรรทัดว่างแทนที่\+ด้วย*ควรแก้ไขได้:

sed 'h;:a;s/[^\n]*/&/4;t;G;ba' file
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.