ธง Perl -pe, -pi, -p, -w, -d, -i, -t?


107

ฉันได้เห็นหลายวิธีในการเรียกใช้รหัสหรือสคริปต์ Perl ด้วยแฟล็กที่แตกต่างกัน อย่างไรก็ตามเมื่อฉันพยายาม google เพื่อดูความหมายของการตั้งค่าสถานะแต่ละรายการส่วนใหญ่ฉันจะได้รับผลลัพธ์ไปยังไซต์ Perl ทั่วไปและไม่พบข้อมูลเฉพาะเกี่ยวกับแฟล็กหรือการใช้งานที่นั่น

ด้านล่างนี้คือค่าสถานะที่ฉันพบบ่อยที่สุดและฉันไม่รู้ว่าหมายถึงอะไร:

  • perl -pe
  • perl -pi
  • perl -p
  • Perl -w
  • perl -d
  • perl -i
  • perl -t

ฉันจะขอบคุณมากถ้าคุณบอกฉันว่าแต่ละความหมายและบางกรณีใช้สำหรับพวกเขาหรืออย่างน้อยก็บอกวิธีการค้นหาความหมายของพวกเขา


21
googling สำหรับคำตอบพื้นฐานเกี่ยวกับ perl มักจะนำคุณไปยังไซต์ที่ไม่ช่วยเหลือจริงๆ ตรวจสอบเอกสารของ perl ก่อนเสมอ
ysth


3
วินาที. ในกรณีนี้perldoc perlrunมีรายการตัวเลือกบรรทัดคำสั่งทั้งหมดที่ Perl ยอมรับ
Sherm Pendley

1
ปัญหาของ Google: เครื่องหมายลบถูกแปลโดย Google ว่าหมายถึง "ไม่รวมคำนี้" เพื่อหลีกเลี่ยงพฤติกรรมนี้ให้วางคำที่มีเครื่องหมายลบในเครื่องหมายคำพูด
Roger Krueger

คำตอบ:


147

ใช่ Google เป็นฉาวโฉ่เรื่องยากสำหรับการหาค่าเครื่องหมายวรรคตอนและโชคไม่ดี, Perl ไม่ดูเหมือนจะเป็นส่วนใหญ่สร้างขึ้นจากเครื่องหมายวรรคตอน :-)

สวิทช์บรรทัดคำสั่งมีรายละเอียดทั้งหมดในperlrun (หาได้จากบรรทัดคำสั่งโดยการโทรperldoc perlrun)

เข้าไปในตัวเลือกสั้น ๆ ทีละคน:

-p: วางลูปการพิมพ์รอบคำสั่งของคุณเพื่อให้ทำงานกับแต่ละคำสั่ง
    บรรทัดของอินพุตมาตรฐาน ใช้เป็นส่วนใหญ่เพื่อให้ Perl สามารถเอาชนะไฟล์
    กางเกงออกในแง่ของพลังและความเรียบง่าย :-)
-n: วางลูปที่ไม่ใช่การพิมพ์ไว้รอบ ๆ คำสั่งของคุณ
-e: อนุญาตให้คุณจัดเตรียมโปรแกรมเป็นอาร์กิวเมนต์แทน
    กว่าในไฟล์ คุณไม่ต้องการที่จะต้องสร้างสคริปต์
    ไฟล์สำหรับ Perl หนึ่งซับทุกตัว
-i: แก้ไขไฟล์อินพุตของคุณในตำแหน่ง (ทำการสำรองข้อมูลไฟล์
    ต้นฉบับ). สะดวกในการแก้ไขไฟล์โดยไม่ต้องใช้ {copy,
    ลบต้นฉบับเปลี่ยนชื่อ}
-w: เปิดใช้งานคำเตือนบางอย่าง ตัวแปลงรหัส Perl ที่ดีจะใช้สิ่งนี้
-d: รันภายใต้โปรแกรมแก้ไขข้อบกพร่อง Perl สำหรับการดีบักรหัส Perl ของคุณ
    เห็นได้ชัด
-t: ถือว่ารหัส "แปดเปื้อน" (น่าสงสัย) บางอย่างเป็นคำเตือน (เหมาะสม
    โหมดสกปรกจะเกิดข้อผิดพลาดกับรหัสที่น่าสงสัยนี้) ใช้กับเนื้อวัว
    เพิ่มความปลอดภัย Perl โดยเฉพาะอย่างยิ่งเมื่อเรียกใช้รหัสสำหรับอื่น ๆ
    ผู้ใช้เช่นสคริปต์ setuid หรือเนื้อหาเว็บ

1
perldoc perlrunผมไม่ได้สังเกตเห็นว่าคุณจะเรียกว่า ฉันลบคำตอบแล้ว :-)
Alan Haggai Alavi

4
-wโดยทั่วไปจะหลีกเลี่ยงได้เนื่องจากเปิดใช้คำเตือนสำหรับโค้ดทั้งหมดรวมถึงโมดูล CPAN ที่ไม่ได้เขียนคำเตือนไว้ในใจ ผลลัพธ์โดยทั่วไปค่อนข้างมีเสียงดังและไม่มีประโยชน์เลย
duskwuff -inactive-

9
-wโดยทั่วไปจะหลีกเลี่ยงได้ แต่ควรแทนที่ด้วยuse warningsรหัสของคุณเอง
plusplus

6
@duskwuff: โดยทั่วไปฉันเห็นด้วยและฉันทำuse warningsในรหัสของตัวเอง แต่ -w มีประโยชน์ - ช่วยกำจัดโมดูล CPAN ที่เขียนไม่ดีออกไป :-)
Sherm Pendley

2
@IanBytchek อาร์กิวเมนต์ที่อาจ / ต้องใช้พารามิเตอร์เพิ่มเติมไม่สามารถอยู่ในรายการบีบอัดได้ -iใช้ส่วนขยายสำหรับการสำรองข้อมูล -eรับคำสั่ง perl ในตัว-0ep คุณกำลังบอก perl ว่า 'p' เป็นคำสั่ง perl แทนที่จะเป็นอาร์กิวเมนต์ นั่นจะไม่ได้ผลดีเลย
tjd

10

-pธงพื้นรันสคริปต์ด้วย

while (<>) {
# exec here
}
continue {
    print or die "-p destination: $!\n";
}

-e ช่วยให้คุณส่งสคริปต์ไปยัง STDIN

perl -e '$x = "Hello world!\n"; print $x;'

-iกำกับล่ามที่ข้อมูลทั้งหมดที่ส่งผ่านไปยังSTDINสคริปต์การเรียกใช้งานจะต้องทำแทน

-wเหมือนกับuse warnings;แต่ในขอบเขตระดับโลกแทนที่จะเป็นระดับท้องถิ่น

-d เรียกใช้โปรแกรมแก้ไขข้อบกพร่อง Perl


2
-wไม่เหมือนกับuse warningsไฟล์หลังถูกกำหนดขอบเขตไปที่ไฟล์ในเครื่อง
plusplus

plusplus จริงปะคำตอบ
zellio

2
การส่งผ่านสคริปต์เป็นอาร์กิวเมนต์ไม่เหมือนกับการส่งผ่านบน STDIN -i ใช้ชื่อไฟล์จากรายการอาร์กิวเมนต์ไม่ใช่ stdin ในขณะที่ STDIN มักเกี่ยวข้องกับเทอร์มินัลควบคุมและได้รับการสืบทอดมาจากเชลล์ที่อ่าน stdin และตั้งค่ารายการอาร์กิวเมนต์เป็น perl แต่ไม่ใช่สิ่งเดียวกัน
William Pursell

8

อื่น ๆ ได้กล่าวถึง perlrun หากคุณใช้ B :: Deparse คุณจะเห็นความหมาย (สำหรับสิ่งต่างๆส่วนใหญ่):

$ perl -MO=Deparse   -p  -e 1
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

1 แสดงโดย "???" เนื่องจากมีการปรับให้เหมาะสม

$ perl -MO=Deparse   -p -i  -e 1
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

-i ตั้ง $ ^ ฉันชอบ

$ perl -MO=Deparse   -p -i.bak  -e 1
BEGIN { $^I = ".bak"; }
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

แต่จำไว้ <ARGV> ใช้ 2 อาร์กิวเมนต์เปิดเพื่อให้ไม่ได้มีชื่อไฟล์ที่เริ่มต้นด้วย> <หรือเริ่ม / |จบลงด้วยการ


4

นอกจากนี้ยังมีธงสำคัญอย่างหนึ่ง-nซึ่งไม่ได้กล่าวถึงในรายการ

-nทำงานเหมือนกับ-pเพียง แต่ไม่พิมพ์$_ตามค่าเริ่มต้น สิ่งนี้มีประโยชน์มากในการกรองไฟล์ข้อความ

ด้วยวิธีนี้ Perl สามารถแทนที่ได้grep | sedในซับเดียว

ตัวอย่างเช่น:

perl -ne 'print "$1\n" if /Messages read: (\d+)/' <my_input.txt

จะพิมพ์ค่าจำนวนเต็มทั้งหมดที่พบหลัง "ข้อความอ่าน:" และไม่มีอะไรเพิ่มเติม


สิ่งนี้สามารถทำให้ง่ายขึ้นได้ ไม่จำเป็นต้องมี "พิมพ์" $ 1 \ n "" คุณสามารถใช้ "พิมพ์" แทนได้
กินเอลิเซียม

ไม่มันไม่print $1ได้ไม่เหมือนกับprint( print $_)
rustyx

มันสามารถ: จะพิมพ์echo abc | perl -nw -e "print if (1)" abcไม่จำเป็นต้อง$1อ้างอิง
กินเอลิเซียม

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