การกำหนดหมายเลขบรรทัด - ใช้ nl


13

งานของคุณคือการใช้โปรแกรมคล้ายกับnlเครื่องมือบรรทัดคำสั่งจากยูทิลิตี้หลักของ GNU

ช่องโหว่มาตรฐานถูกแบน

คุณไม่สามารถใช้ฟังก์ชันโปรแกรมหรือยูทิลิตี้ในตัวหรือภายนอกสำหรับกำหนดหมายเลขบรรทัดของไฟล์หรือสตริงเช่นnlตัวมันเองหรือ=คำสั่งใน GNU sed

สเปค

อินพุต

โปรแกรมยอมรับชื่อไฟล์เป็นอาร์กิวเมนต์ รหัสของคุณไม่จำเป็นต้องข้ามแพลตฟอร์ม รูปแบบชื่อไฟล์ของระบบปฏิบัติการที่ใช้รหัสควรนำมาใช้เช่นถ้าคุณเกิดขึ้นได้บน Windows, คั่นไดเรกทอรีสามารถหรือ\/

คุณต้องสามารถใช้ไฟล์อินพุต 64 ไฟล์รวมถึง-หากมีการระบุไว้ หากได้รับมากกว่า 64 ให้จัดการ 64 คนแรกเท่านั้น

ในรายการชื่อไฟล์-หมายถึงอินพุตมาตรฐาน

หากมีการกำหนดชื่อไฟล์ให้อ่านจากไฟล์ตามลำดับที่ได้รับและต่อเนื้อหาเข้าด้วยกันโดยแทรกบรรทัดใหม่ระหว่างแต่ละไฟล์และท้ายบรรทัด หากคุณไม่สามารถอ่านจากชื่อไฟล์อย่างน้อยหนึ่งไฟล์ (เนื่องจากไฟล์ไม่มีอยู่หรือคุณไม่ได้รับอนุญาตให้อ่าน) อย่าเพิกเฉย หากชื่อไฟล์ทั้งหมดที่ระบุไม่ถูกต้องจะไม่แสดงผลใด ๆ

หากไม่มีการกำหนดชื่อไฟล์ให้อ่านจากอินพุตมาตรฐาน อ่านจากอินพุตมาตรฐานเท่านั้นหากไม่มีการกำหนดชื่อไฟล์หรือ-ได้รับ

เอาท์พุต

เอาท์พุทโปรแกรมประสงค์จะออกมาตรฐานการป้อนข้อมูลที่มีเส้นเลขจึง (คุณอาจคิดว่าการป้อนข้อมูลที่มี\n, \r\nหรือ\rปลายสายรับแล้วแต่จำนวนใดจะสะดวกสำหรับคุณ แต่ที่หนึ่งระบุ):

<5 spaces>1<tab><content of line 1 of input>
<5 spaces>2<tab><content of line 2 of input>
...
<4 spaces>10<tab><content of line 10 of input>
...
<3 spaces>100<tab><content of line 100 of input>
...
...

มีการจัดสรรพื้นที่ 6 อักขระสำหรับหมายเลขบรรทัดและจะถูกแทรกที่ส่วนท้ายของอักขระเหล่านี้ ส่วนที่เหลือจะกลายเป็นช่องว่าง (เช่น1จะมี 5 ช่องว่างนำหน้า22จะมี 4 ช่องว่างนำหน้า ... ) 999999ถ้าใส่นานพอสมควรในที่สุดคุณจะทำงานออกจากพื้นที่จำนวนบรรทัดที่บรรทัด คุณต้องไม่ส่งออกอะไรหลังจากบรรทัด 999999

หากอินพุตว่างเปล่าให้ส่งเอาต์พุตอะไร

สถานะการออก

จำนวนที่ต่ำกว่าจะมีลำดับความสำคัญ: หากพบข้อผิดพลาด 1 และ 2 ให้ออกพร้อมสถานะ 1

ออกด้วยสถานะ 0 หากได้รับอินพุตเรียบร้อยแล้วและบรรทัดที่มีหมายเลขและเอาต์พุตสำเร็จ

ออกด้วยสถานะ 1 หากไม่พบไฟล์หนึ่งไฟล์ขึ้นไปที่ระบุในบรรทัดคำสั่งหรือไม่สามารถอ่านได้

ออกจากสถานะ 2 หากได้รับไฟล์มากเกินไป (มากกว่า 64)

ออกจากสถานะ 3 หากอินพุตยาวเกินไป (มากกว่า 999999 บรรทัด)

เกณฑ์การให้คะแนน

นี่คือ code-golf - โปรแกรมที่สั้นที่สุดชนะ!

ฉันอาจเพิ่มโบนัสในภายหลังสำหรับการใช้งานตัวเลือกบางอย่างที่nlมี ไม่มีโบนัสในขณะนี้


การกำหนดหมายเลขบรรทัดอย่างต่อเนื่องหรือสั้นกว่านั้นคือ "รีเซ็ต" ตัวเองสำหรับแต่ละไฟล์
britishtea

@britishtea มันต่อเนื่อง

1
ดังนั้นจำเป็นต้องใช้โหนดหรือไม่ถ้าเราต้องการส่งบางสิ่งใน js? หรือเราสามารถใช้ฟังก์ชั่น args หรือprompt()เลียนแบบโปรแกรม args และ stdin ได้ไหม?
DankMemes

1
ไฟล์ไบนารีหรือไม่ การเข้ารหัส? เครื่องหมาย Unicode?
edc65

คำตอบ:


6

Bash, 121

s=$[2*($#>64)]
for f in "$@";{ [ -f $f ]||s=1;}
((s))&&exit $s
awk '{if(NR>=10**6){exit 3}printf("%6d\t%s\n",NR,$0)}' $@

1
คุณสามารถทำให้ifนิพจน์ของคุณสั้นลงเล็กน้อยถ้าคุณใช้นิพจน์ทางคณิตศาสตร์เช่น(($#>64))&&s=2
Digital Trauma

2
@ DigitalTrauma ฉันเรียนรู้สิ่งหนึ่ง!
Sammitch

1
คุณสามารถแทนที่s=0;(($#>64))&&s=2ด้วยs=$[2*($#>64)], (($s==0))||มี((s))&&และคำสั่งด้วยif [ -f "$f" ]||s=1
เดนนิส


2
awkจะต่อกันถ้าผ่านหลาย ๆ ไฟล์ดังนั้นสิ่งนี้จึงนับว่าเป็นการใช้งานอย่างไม่มีประโยชน์ของ cat ;-) ฉันคิดว่ามันจะใช้ได้ผล:awk '...' $@
Digital Trauma

2

ทับทิม, 195

o,l=$*[64]?[2]:[],999999
($*==[]?[?-]:$*).each{|n|f=n==?-?STDIN: open(n)rescue o<<1&&next
s=f.read.lines
s[l]?o<<3:1
puts s[0..l].map.with_index(1){|l,i|i.to_s.rjust(6)+?\t+l}}
exit !o[0]?0:o.min

ผมคิดว่าใช้นามแฝงSTDIN $<
Martin Ender

มันเป็นนามแฝงสำหรับARGFซึ่งจะอ่านจากไฟล์ที่เหลือที่ให้ไว้เป็นอาร์กิวเมนต์เช่นกัน ฉันคิดว่าสิ่งนี้สามารถลงเล่นกอล์ฟต่อไปได้ด้วยวิธีARGFใดวิธีหนึ่ง (มันดูเหมือนว่าจะรับรู้"-"ว่าเป็น stdin)
britishtea

britishteanl: 4: ในblock in <main>': undefined method [] 'สำหรับ # <ตัวระบุ: 0x000006002980c8> (NoMethodError) จาก britishteanl: 2: ในeach' from britishteanl:2:in <หลัก>' ผิดปกติอะไร ฉันวิ่งเป็นruby britishteanl folder/filename

ฉันสงสัยว่ามันแตกต่างในเวอร์ชั่น Ruby ฉันรันตัวอย่างทั้ง Ruby 2.0.0 และ Ruby 2.1.2 โดยไม่มีปัญหา คุณใช้เวอร์ชั่นอะไร
britishtea

2

Perl, 84 + 2 ( -pl) = 86 ไบต์

perl -ple'BEGIN{map{-r||exit 1}@ARGV;@ARGV>63&&exit 2}$.>=1e6&&exit 3;$_=printf"%5d\t%s",$.,$_'

Deparsed:

perl -MO=Deparse -ple'BEGIN{map{-r||exit 1}@ARGV;@ARGV>63&&exit 2}$.>=1e6&&exit 3;$_=printf"%5d\t%s",$.,$_' output.txt; echo $?

BEGIN { $/ = "\n"; $\ = "\n"; }
sub BEGIN {
    map {exit 1 unless -r $_;} @ARGV;
    exit 2 if @ARGV > 63;
}
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    exit 3 if $. >= 1000000;
    $_ = printf("%5d\t%s", $., $_);
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

สิ่งสำคัญที่ควรทราบ:

  • -pล้อมรอบโปรแกรมที่กำหนดด้วย-eในwhile/ continueloop
  • BEGIN รหัสจะถูกดำเนินการก่อนส่วนหลัก (โดยนัย)
  • การทดสอบไฟล์จะ-rล้มเหลวหากไฟล์ไม่มีอยู่!-eและเป็นค่าเริ่มต้นในการทดสอบ$_ซึ่งกำหนดโดยปริยายmap { ... } @ARGV
  • $. เก็บหมายเลขบรรทัดปัจจุบัน
  • ส่วนที่เหลือควรอธิบายด้วยตนเอง;)

คำตอบที่ยอดเยี่ยมและยินดีต้อนรับสู่ไขปริศนาและการเขียนโปรแกรมกอล์ฟ! บางทีคุณสามารถแก้ไขเพื่อเพิ่มคำอธิบายวิธีการทำงานของรหัสของคุณ
wizzwizz4

1

หลาม 173

import os,sys
c=0
l=1
for f in sys.argv[1:]:
    if c>64:exit(2)
    if not os.path.isfile(f):exit(1)
    c+=1
    for x in open(f):
        if l>=10**6:exit(3)
        print '%6d\t%s'%(l,x),;l+=1

ผมคิดว่ารหัสของคุณในปัจจุบันคือการขาดหายไปสำหรับ- sys.stdinทางออกที่เป็นไปได้อาจเป็นสิ่งที่ต้องการfh=sys.stdin if f=='-' else open(f)แล้วไปด้วยx=fh.readline()หรือไม่! น่าเสียดายที่มันไม่ได้ทำให้สั้นลง :)
เดฟ J

1

J (162)

exit(((2*64<#)[exit@3:`(stdout@(,&LF)@;@(,&TAB@(6&":)&.>@>:@i.@#,&.>]))@.(1e6>#)@(<;.2)@(1!:1)@(<`3:@.('-'-:]))&.>@;@{.@(_64&(<\))) ::1:)]`(]&<&'-')@.(0=#)2}.ARGV

คำอธิบาย:

  • ]`(]&<&'-')@.(0=#)2}.ARGV: รับอาร์กิวเมนต์บรรทัดคำสั่งและลบสองรายการแรก (เนื่องจากเป็นล่ามและชื่อไฟล์สคริปต์) หากรายการผลลัพธ์ว่างเปล่าส่งคืน['-'](เช่นราวกับว่าผู้ใช้ผ่านเท่านั้น-) มิฉะนั้นส่งคืนรายการไม่เปลี่ยนแปลง
  • (... ::1:): หากฟังก์ชั่นด้านในล้มเหลวให้ส่งคืน1มิฉะนั้นคืนสิ่งที่ฟังก์ชันภายในกลับมา
  • ((2*64<#)[... ): ประเมินฟังก์ชั่นด้านในและโยนผลลัพธ์ออกไป แล้วถ้าความยาวของรายการผ่านไม่ได้สูงกว่า64ผลตอบแทนอย่างอื่นกลับ02
  • &.>@;@{.@(_64&(<\)): รับ64องค์ประกอบมากที่สุดจากรายการและสำหรับแต่ละรายการจะเรียกใช้ฟังก์ชันต่อไปนี้:
    • (1!:1)@(<`3:@.('-'-:])): ถ้าองค์ประกอบนั้น-อ่านเนื้อหาของ file descriptor 3(stdin) มิฉะนั้นอ่านเนื้อหาของไฟล์ที่ชื่อโดยองค์ประกอบนั้น หากล้มเหลว (ไฟล์เช่นไม่ได้อยู่) 1รหัสข้างต้นจะจับมันและผลตอบแทน
    • exit@3:`(... )@.(1e6>#)@(<;.2): แยกสตริงที่ส่วนท้ายของบรรทัด หากมี 1.000.000 3หรือหลายเส้นออกจากที่มีสถานะ มิฉะนั้น:
      • ,&TAB@(6&":)&.>@>:@i.@#: สร้างตัวเลขสำหรับแต่ละบรรทัดจัดรูปแบบพวกเขาในคอลัมน์ 6 หลักและเพิ่ม a TABไปยังจุดสิ้นสุดของแต่ละสตริง
      • ,&.>]: เพิ่มแต่ละหมายเลขที่ด้านหน้าของแต่ละบรรทัด
      • stdout@(,&LF)@;LFแล้วส่งออกสิ่งที่ทั้งตามด้วยเป็นพิเศษ
  • exit: exit ด้วยค่าส่งคืนของฟังก์ชันนั้น

1

Ruby, 76 ไบต์

หนึ่งไบต์สำหรับpแฟล็ก ruby -p nl.rbทำงานด้วย

BEGIN{x=$*.size-65}
exit 2if$*.size==x
exit 3if$.>999999
$_="%6d"%$.+?\t+$_

stdin หรืออาร์กิวเมนต์ไฟล์ได้รับการจัดการโดยอัตโนมัติโดย Ruby มันออกแล้วด้วยรหัส 1 หากไม่มีไฟล์อาร์กิวเมนต์ $.คือจำนวนบรรทัดที่อ่านแล้ว $*คืออาร์กิวเมนต์บรรทัดคำสั่งและไฟล์จะแตกออกเมื่ออ่านไฟล์ pธงดำเนินการBEGINป้องกันและตัดส่วนที่เหลือของโปรแกรมภายในห่วงขณะ-ได้รับการพิมพ์โดยใช้$_เป็นอินพุต / เอาต์พุต


ข้อมูลจำเพาะบอกว่าคุณควรจัดการกับ 64 อินพุตแรกถ้าให้มากกว่า 64 แทนที่จะยอมแพ้ในตอนเริ่มต้น
Anders Kaseorg

@AndersKaseorg แก้ไขแล้ว
daniero

1

Perl, 125 122 ไบต์

@a=@ARGV;for(@a){$i++>63&&exit 2;($_ eq '-'or-e$_)or next;@ARGV=$_;while(<>){$c>1E6-2&&exit 3;printf"%5d\t%s",++$c,$_}say}

สิ่งนี้ไม่เป็นไปตามข้อกำหนดที่เกี่ยวกับอาร์กิวเมนต์สูงสุด 64 รายการและสถานะการออก
Anders Kaseorg

@AndersKaseorg แก้ไขแล้ว!
Gowtham

0

C, 362 359

เพียงเพื่อความสนุกของมัน ;-) ทำงานร่วมกับ LF หรือ CR / LF linefeeds

#include<stdio.h>
#define R return
#define P printf(
e,t,l;void*f;r(){P"% 6d\t",++l);for(;(t=fgetc(f))^-1&&l<1000000;){if(ferror(f))R 1;P"%c",t);if(t==10)P"% 6d\t",++l);}P"\n");R l<1000000?0:3;}main(int c,char**v){e=c>65?2:0;for(++v;*v||c<2;++v){t=c<2||!strcmp(*v,"-")?f=stdin,0:!(f=fopen(*v,"rb"));if(t||(t=r()))e=!e|(e>t)?t:e;if(f&&f!=stdin)fclose(f);}R e;}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.