7 ms·
My favorite perl one liner is a globbed search and replace. It even has it's own website: http://perlpie.com/ http://perlpie.com/ perl -p -i -e 's/foo/bar
by shanemhansen 10y ago
My favorite perl one liner is a globbed search and replace. It even has it's own website: http://perlpie.com/ http://perlpie.com/
perl -p -i -e 's/foo/bar/gi' ./*.txt
- scrame 10y agoThe -i switch takes an optional string that creates a backup of the file with that extension. To use your example (with zsh blobbing): perl -p -i.bak -e 's/foo/bar/gi' **/*.txt Recursively replaces foo with bar on every .txt file in a hierarchy and saves the original file with a .bak extension, along with the in-place edit in the original.
- jxy 10y agoWhat is the advantage of this over sed?
- JadeNB 10y ago> What is the advantage of this over sed? The same as for anything that could be done in the shell, but is done with a full-fledged programming language: when you discover you need to tweak it to accommodate an additional requirement, it's easy in Perl but hard in sed.
- nilved 10y agoIf that was the case you think you'd reach for literally any other language than Perl.
- untoreh 10y agoperl has the best regex, or one of the best, also it is the only other language other than python which is installed by default in common distros afaik
- aduitsis 10y agoIf you feel unproductive or uncomfortable with Perl, you should avoid it and use whatever language strikes your fancy. Many people however are extremely comfortable and productive with Perl, for a wide variety of reasons. It's really an awesome language that has proven its vast usefulness a long time ago.
- collyw 10y agoPerl is usually my goto language for that sort of task. It has loads of built in features for interacting with the system.
- swuecho 10y agofor me, I do not know sed or awk.
- paulmd 10y agoPerl's substitution and translation facilities work pretty much the same way as sed, if you understand sed you can just drop those operations into Perl. For example, sed -i 's/old/new/' will do an in-place replacement of all strings 'old' with the string 'new'. I find that you do escaping a little differently with sed though. For example you need to escape +'s for them to have their normal "one or more matches" semantics. Might just be an abnormality of my environment (Cygwin).
- tyingq 10y agoNot much over GNU sed. A lot of these perl one liners are from the old days, from unix admins that had versions of sed (or find, etc) that didn't have fancy features like -i (inplace edit).
- mark-wagner 10y agoAlso in the old days tools like sed and awk had more arbitrary limitations. E.g., line length was limited to something (reasonable) like 8192 bytes but input data I was processing was not reasonable. GNU sed does not have that limit: https://www.gnu.org/software/sed/manual/html_node/Limitations.html https://www.gnu.org/software/sed/manual/html_node/Limitation...
- dozzie 10y ago> What is the advantage of [perl -pi -e 's///'] over sed? PCRE and /e flag.
- paulmd 10y agoThey're functionally interchangeable for simple usage (minus some perl-specific stuff like PCRE). As I note below, escape behavior is a little different because sed wants you to escape +'s to have the normal regex semantics ("one or more matches"). And I actually think Perl is correct here and you should only need to escape those characters if you want literal matches, but I have a weird environment (Cygwin) and it's possible the sed build there is a little messed up. The major difference for me is that Perl can match across multiple lines using the -0777 flag. I've been doing a lot of regex-based mass manipulation of source code lately and most people write functions across multiple lines. You can't do that with sed without multi-line appending and it gets really ugly really fast. Sed is pretty much just single line matches only. For example, I had 100-odd classes with getters for certain values but not setters. So I did: grep -rle "getAddTime" | while read line; do if ! grep -q "setAddTime" $line ; then echo $line; perl -i -0777 -pe 's/public\s+Date\s+getAddTime\s*\(\s*\)\s*\{[\s\w=;]+\}/$&\n\n public void setAddTime(Date addTime) { this.addTime = addTime; }/' $line; fi done translation: look for files that contain getAddTime, if they do not contain setAddTime then find the string "public Date getAddTime() {...} and append the setter after that". There are a few edge cases you could hit there but it was close enough to work on my codebase. I wish Perl would do an inplace edit of a file without creating a backup, though. I am under source control so there's no harm in just operating right on the files. It's not the end of the world to follow up with a rm -r *.bak I guess, but it's annoying. At least they're in my git-ignore which helps a little.
- throwbsidbdk 10y agoFun factoid most have forgotten: regex is perl. The beginnings are elsewhere but regex as we know it was designed as part of the language and the engine was pulled out and reused when people found how useful it was. Perls regex parser is still far above the features in more modern languages, supporting, among other things, code execution within capture groups. If I remember right the perl regex parser is actually Turing complete
- TazeTSchnitzel 10y agoThus the PCRE regex library, Perl-Compatible Regular Expressions, for instance.
- mitchty 10y agoIt works on non linux unixes.
- sigzero 10y agoNone really. I would think if you use Perl, you would probably use the one line from Perl is all. Also sed doesn't have the in place function on Solaris (and AIX) by default I believe. So with Perl, you can do it everywhere.
- dahart 10y agoFor me, one part laziness and one part flexibility, and the flexibility part I might be rationalizing. :P. Perl's a superset of what can be done with sed, so I tend to use perl for this case even when sed would do, just because I can remember the perl command line args and regex syntax off the top of my head. I often have to take a trip to the sed man page if I use sed. It's easier for me to add special corner cases to a perl one-liner, etc. That said, sed is simpler, sometimes less to type, sometimes there on systems where perl isn't (though that seems uncommon these days). But I'm using sed more often, and the more I use it the more familiar it is. Nicer to have two good tools around than just one, right?
- electrum 10y agoOne big advantage is portability / compatibility. For example, Linux uses GNU sed but Mac OS X uses BSD sed. I've run into issues where a sed script works on one but not the other. Using perl in sed mode avoids this.
- nilved 10y agoI try to avoid Perl when I can (not that sed is much better.) sed -i "s/foo/bar/gi" ./*.txt
- shanemhansen 10y agoI actually have trouble remembering perl pie, even though it's got a cute name. Usually I end up running something like this. git grep -l something | xargs sed -i.bak -e 's/something/else/g' Because the longer chain is easier to remember for me.
- sndean 10y agoAwk is a easier for me to remember than sed or perl, just because "sub" (for substitution) is in there: awk '{gsub(/this/,"that")}; 1' Edit: I just learned that "s" in the sed command is for substitute... (http://www.grymoire.com/Unix/Sed.html http://www.grymoire.com/Unix/Sed.html) Well, maybe I'll be able to remember that.
- nilved 10y agoI think you'd like my `git sed` script. https://github.com/devlinzed/dotfiles/blob/master/bin/git-sed https://github.com/devlinzed/dotfiles/blob/master/bin/git-se...
- JadeNB 10y agoAs the URL (but not, sadly, the website itself) suggests, you're exhausting yourself with all that negativity; you can remove two '-'s (as well as two ' 's), and get a much tastier command line: perl -pie 's/foo/bar/gi' ./*.txt
- pre_action 10y agoThe 'e' character is seen as an argument to the '-i' switch, meaning this command line will yield `Can't open perl script "s/foo/bar/gi": No such file or directory`
- JadeNB 10y agoSigh; I am not making much of a show of my Perl knowledge today. (I messed up a Perl find-alike elsethread.) Thanks for setting me straight.