Perl has a large number of command-line options that can help to make your programs more concise and open up many new possibilities for ...
MORE:
Togglenavigation
Perl.com
ABOUT
AUTHORS
CATEGORIES
#
TAGS
PerlCommand-LineOptions
Aug10,2004by
DaveCross
Perlhasalargenumberofcommand-lineoptionsthatcanhelptomakeyourprogramsmoreconciseandopenupmanynewpossibilitiesforone-offcommand-linescriptsusingPerl.Inthisarticlewe’lllookatsomeofthemostusefulofthese.
SafetyNetOptions
TherearethreeoptionsIliketothinkofasa“safetynet,”astheycanstopyoufrommakingafoolofyourselfwhenyou’redoingsomethingparticularlyclever(orstupid!).Andwhiletheyaren’tevernecessary,it’srarethatyou’llfindanexperiencedPerlprogrammerworkingwithoutthem.
Thefirstoftheseis-c.Thisoptioncompilesyourprogramwithoutrunningit.Thisisagreatwaytoensurethatyouhaven’tintroducedanysyntaxerrorswhileyou’vebeeneditingaprogram.WhenI’mworkingonaprogramInevergomorethanafewminuteswithoutsavingthefileandrunning:
$perl-c
Thismakessurethattheprogramstillcompiles.It’sfareasiertofixproblemswhenyou’veonlymadeafewchangesthanitistotypeinacoupleofhundredoflinesofcodeandthentrytodebugthat.
Thenextsafetynetisthe-woption.ThisturnsonwarningsthatPerlwillthengiveyouifitfindsanyofanumberofproblemsinyourcode.Eachofthesewarningsisapotentialbuginyourprogramandshouldbeinvestigated.InmodernversionsofPerl(since5.6.0)the-woptionhasbeenreplacedbytheusewarningspragma,whichismoreflexiblethanthecommand-lineoptionsoyoushouldn’tuse-winnewcode.
Thefinalsafetynetisthe-Toption.ThisoptionputsPerlinto“taintmode.”Inthismode,Perlinherentlydistrustsanydatathatitreceivesfromoutsidetheprogram’ssource–forexample,datapassedinonthecommandline,readfromafile,ortakenfromCGIparameters.
Tainteddatacannotbeusedinanexpressionthatinteractswiththeoutsideworld–forexample,youcan’tuseitinacalltosystemorasthenameofafiletoopen.Thefulllistofrestrictionsisgivenintheperlsecmanualpage.
Inordertousethisdatainanyofthesepotentiallydangerousoperationsyouneedtountaintit.Youdothisbycheckingitagainstaregularexpression.AdetaileddiscussionoftaintmodewouldfillanarticleallbyitselfsoIwon’tgointoanymoredetailshere,butusingtaintmodeisaverygoodhabittogetinto–particularlyifyouarewritingprograms(likeCGIprograms)thattakeunknowninputfromusers.
Actuallythere’soneotheroptionthatbelongsinthissetandthat’s-d.ThisoptionputsyouintothePerldebugger.Thisisalsoasubjectthat’stoobigforthisarticle,butIrecommendyoulookat“perldocperldebug”orRichardFoley’sPerlDebuggerPocketReference.
Command-LinePrograms
ThenextfewoptionsIwanttolookatmakeiteasytorunshortPerlprogramsonthecommandline.Thefirstone,-e,allowsyoutodefinePerlcodetobeexecutedbythecompiler.Forexample,it’snotnecessarytowritea“HelloWorld”programinPerlwhenyoucanjusttypethisatthecommandline.
$perl-e'print"HelloWorld\n"'
Youcanhaveasmany-eoptionsasyoulikeandtheywillberunintheorderthattheyappearonthecommandline.
$perl-e'print"Hello";'-e'print"World\n"'
NoticethatlikeanormalPerlprogram,allbutthelastlineofcodeneedstoendwitha;character.
Althoughitispossibletousea-eoptiontoloadamodule,Perlgivesyouthe-Moptiontomakethateasier.
$perl-MLWP::Simple-e'printhead"http://www.example.com"'
So-Mmoduleisthesameasusemodule.Ifthemodulehasdefaultimportsyoudon’twantimportedthenyoucanuse-minstead.Using-mmoduleistheequivalentofusemodule(),whichturnsoffanydefaultimports.Forexample,thefollowingcommanddisplaysnothingastheheadfunctionwon’thavebeenimportedintoyourmainpackage:
$perl-mLWP::Simple-e'printhead"http://www.example.com"'
The-Mand-moptionsimplementvariousnicepiecesofsyntacticsugartomakeusingthemaseasyaspossible.Anyargumentsyouwouldnormallypasstotheusestatementcanbelistedfollowingan=sign.
$perl-MCGI=:standard-e'printheader'
Thiscommandimportsthe“:standard”exportsetfromCGI.pmandthereforetheheaderfunctionbecomesavailabletoyourprogram.Multipleargumentscanbelistedusingquotesandcommasasseparators.
$perl-MCGI='header,start_html'-e'printheader,start_html'
Inthisexamplewe’vejustimportedthetwomethodsheaderandstart_htmlasthosearetheonlyonesweareusing.
ImplicitLoops
Twoothercommand-lineoptions,-nand-p,addloopsaroundyour-ecode.Theyarebothveryusefulforprocessingfilesalineatatime.Ifyoutypesomethinglike:
$perl-n-e'somecode'file1
ThenPerlwillinterpretthatas:
LINE:
while(<>){
#yourcodegoeshere
}
Noticetheuseoftheemptyfileinputoperator,whichwillreadallofthefilesgivenonthecommandlinealineatatime.Eachlineoftheinputfileswillbeput,inturn,into$_sothatyoucanprocessit.Asaexample,try:
$perl-n-e'print"$.-$_"'file
Thisgetsconvertedto:
LINE:
while(<>){
print"$.-$_"
}
Thiscodeprintseachlineofthefiletogetherwiththecurrentlinenumber.
The-poptionmakesthateveneasier.Thisoptionalwaysprintsthecontentsof$_eachtimearoundtheloop.Itcreatescodelikethis:
LINE:
while(<>){
#yourcodegoeshere
}continue{
printordie"-pdestination:$!\n";
}
Thisusesthelittle-usedcontinueblockonawhilelooptoensurethattheprintstatementisalwayscalled.
Usingthisoption,ourlinenumbergeneratorbecomes:
$perl-p-e'$_="$.-$_"'
Inthiscasethereisnoneedfortheexplicitcalltoprintas-pcallsprintforus.
NoticethattheLINE:labelistheresothatyoucaneasilymovetothenextinputrecordnomatterhowdeepinembeddedloopsyouare.YoudothisusingnextLINE.
$perl-n-e'nextLINEunless/pattern/;print$_'
Ofcourse,thatexamplewouldprobablybewrittenas:
$perl-n-e'printunless/pattern/'
Butinamorecomplexexample,thenextLINEconstructcouldpotentiallymakeyourcodeeasiertounderstand.
Ifyouneedtohaveprocessingcarriedouteitherbeforeorafterthemaincodeloop,youcanuseaBEGINorENDblock.Here’saprettybasicwaytocountthewordsinatextfile:
$perl-ne'END{print$t}@w=/(\w+)/g;$t+=@w'file.txt
Eachtimeroundtheloopweextractallofthewords(definedascontiguousrunsof\wcharactersinto@wandaddthenumberofelementsin@wtoourtotalvariable$t.TheENDblockrunsaftertheloophascompletedandprintsoutthefinalvaluein$t.
Ofcourse,people’sdefinitionofwhatconstitutesavalidwordcanvary.ThedefinitionusedbytheUnixwc(wordcount)programisastringofcharactersdelimitedbywhitespace.Wecansimulatethatbychangingourprogramslightly,likethis:
$perl-ne'END{print$x}@w=split;$x+=@w'file.txt
Butthereareacoupleofcommand-lineoptionsthatwillmakethatevensimpler.Firstlythe-aoptionturnsonautosplitmode.Inthismode,eachinputrecordissplitandtheresultinglistofelementsisstoredinanarraycalled@F.Thismeansthatwecanwriteourword-countprogramlikethis:
$perl-ane'END{print$x}$x+=@F'file.txt
Thedefaultvalueusedtosplittherecordisoneormorewhitespacecharacters.Itis,ofcourse,possiblethatyoumightwanttosplittheinputrecordonanothercharacterandyoucancontrolthiswiththe-Foption.Soifwewantedtochangeourprogramtosplitonallnon-wordcharacterswecoulddosomethinglikethis:
$perl-F'\W'-ane'END{print$x}$x+=@F'file.txt
Foramorepowerfulexampleofwhatwecandowiththeseoptions,let’slookattheUnixpasswordfile.Thisisasimple,colon-delimitedtextfilewithonerecordperuser.Theseventhcolumninthisfileisthepathoftheloginshellforthatuser.Wecanthereforeproduceareportofthemost-usedshellsonagivensystemwithacommand-linescriptlikethis:
$perl-F':'-ane'$s{$F[6]}++;'\
>-e'END{print"$_:$s{$_}"forkeys%s}'/etc/passwd
OK,soit’slongerthanonelineandtheoutputisn’tsorted(althoughit’squiteeasytoaddsorting),butperhapsyoucangetasenseofthekindsofthingsthatyoucandofromthecommandline.
RecordSeparators
InmypreviousarticleItalkedalotabout$/and$\–theinputandoutputrecordseparators.$/defineshowmuchdataPerlwillreadeverytimeyouaskitforthenextrecordfromafilehandle,and$\containsavaluethatisappendedtotheendofanydatathatyourprogramprints.Thedefaultvalueof$/isanewlineandthedefaultvalueof$\isanemptystring(whichiswhyyouusuallyexplicityaddanewlinetoyourcallstoprint).
Nowintheimplicitloopssetupby-nand-pitcanbeusefultodefinethevaluesof$/and$\.Youcould,ofcourse,dothisinaBEGINblock,butPerlgivesyouaneasieroptionwiththe-0(that’sazero)and-l(that’sanL)command-lineoptions.Thiscangetalittleconfusing(well,itconfusesme)soI’llgoslowly.
Using-0andgivingitahexadecimaloroctalnumbersets$/tothatvalue.Thespecialvalue00putsPerlinparagraphmodeandthespecialvalue0777putsPerlintofileslurpmode.Thesearethesameassetting$/toanemptystringandundefrespectively.
Using-landgivingitnovaluehastwoeffects.Firstly,itautomaticallychompstheinputrecord,andsecondly,itsets$\equalto$/.Ifyougive-lanoctalnumber(andunlike-0itdoesn’taccepthexnumbers)itsets$\tothecharacterrepresentedbythatnumberandalsoturnsonauto-chomping.
Tobehonest,Irarelyusethe-0optionandIusuallyusethe-loptionwithoutanargumentjusttoaddanewlinetotheendofeachlineofoutput.Forexample,I’dusuallywritemyoriginal“HelloWorld”exampleas:
$perl-le'print"HelloWorld"'
IfI’mdoingsomethingthatrequireschangingthevaluesoftheinputandoutputrecordseparatorsthenI’mprobablyoutoftherealmofcommand-linescripts.
In-PlaceEditing
Withtheoptionsthatwehavealreadyseen,it’sveryeasytobuildupsomepowerfulcommand-lineprograms.It’sverycommontoseecommandlineprogramsthatuseUnixI/Oredirectionlikethis:
$perl-pe'somecode'output.txt
Thistakesrecordsfrominput.txt,carriesoutsomekindoftransformation,andwritesthetransformedrecordtooutput.txt.Insomecasesyoudon’twanttowritethechangeddatatoadifferentfile,it’softenmoreconvenientifthealtereddataiswrittenbacktothesamefile.
Youcangettheappearanceofthisusingthe-ioption.Actually,Perlrenamestheinputfileandreadsfromthisrenamedversionwhilewritingtoanewfilewiththeoriginalname.If-iisgivenastringargument,thenthatstringisappendedtothenameoftheoriginalversionofthefile.Forexample,tochangealloccurrencesof“PHP”to“Perl”inadatafileyoucouldwritesomethinglikethis:
$perl-i-pe's/\bPHP\b/Perl/g'file.txt
Perlreadstheinputfilealineatatime,makingthesubstitution,andthenwritingtheresultsbacktoanewfilethathasthesamenameastheoriginalfile–effectivelyoverwritingit.Ifyou’renotsoconfidentofyourPerlabilitiesyoumighttakeabackupoftheoriginalfile,likethis:
$perl-i.bak-pe's/\bPHP\b/Perl/g'file.txt
You’llendupwiththetransformeddatainfile.txtandtheoriginalfilebackedupinfile.txt.bak.Ifyou’reafanofvithenyoumightliketouse-i~instead.
FurtherInformation
Perlhasalargenumberofcommand-lineoptions.Thisarticlehassimplylistedafewofthemostuseful.Forthefulllist(andformoreinformationontheonescoveredhere)seethe“perlrun”manualpage.
Tags
tooling
DaveCross
Browsetheirarticles
Feedback
Somethingwrongwiththisarticle?HelpusoutbyopeninganissueorpullrequestonGitHub
Tweetsbyperlfoundation