3

I'm trying to manipulate multiline CoffeeScript comments in a file using perl. This is my regex:

^\t*###[\S\s]*?^\t*###

When I run this in a script where data is the file data, it does what I expect and replaces all multiline comments with "foo":

$data =~ s{^\t*###[\S\s]*?^\t*###}{"foo"}gme;

However, when I run this on the command line the file is unchanged:

perl -pi -e 's{^\t*###[\S\s]*?^\t*###}{"foo"}gme' file.coffee

I've used similar commands with different regular expressions and without the 'm' option and they all work. Is it the m option that's causing the issue? I'm sure its something simple.

4
  • I'm curious if the filesystem is taking the \t as a literal tab char instead of the actual regex tab? What happens if you try escaping the backslashes? Commented Dec 1, 2013 at 4:31
  • Escape the backslashes as \\t? Commented Dec 1, 2013 at 4:33
  • Yeah, give that a shot. No idea if it'll work though :) Commented Dec 1, 2013 at 4:35
  • I ran perl -pi -e 's{^\\t*###[\S\s]*?^\\t*###}{"foo"}gme' file.coffee and still no joy. Commented Dec 1, 2013 at 4:37

2 Answers 2

4

In the implicit loops set by -n and -p it can be useful to define the values of $/ and $\. Using the -0 option puts Perl in paragraph mode and the special value 0777 puts Perl into file slurp mode.

perl -0777 -i -pe 's{^\t*###[\S\s]*?^\t*###}{"foo"}gme' file.coffee
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for putting this up as an answer for anyone who stumbles across this question.
3

The perl documentation for the -n/-p option states:

assume "while (<>) { ... }" loop around program

This means that each time the -e expression is executed, $_ is one line of the input file. Your s/// expression is expecting to operate on the whole entire file at once, so it won't work in this mode.

6 Comments

Is there any way I can operate on the whole file at once from the command line?
Not in-place that I can find, but you could probably do something like: perl -e 'local $/; $data = <>; $data =~ s/find/replace/; print $data' < file > file.new && mv file.new file
@RyanLynch You can slurp the file.
Thanks @hwnd. I'll think about asking another question now that I know what the issue is.
Try this perl -0777 -i -pe 's{^\t*###[\S\s]*?^\t*###}{"foo"}gme' file.coffee
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.