-1

I need to go through some java files, and pull out the authors after every @author tag. I started out looking at awk, but awk can't remove the unneded parts, and so I came across this.

What I'm running

perl -n -e'/author (.*)/ && print $1' *.java

This prints nothing. If I do

perl -n -e'/author (.*)/ && print $_' *.java

it will (correctly) print the entire line.

I can do this, and it does accomplish my goal, but I still want to know why my capture group isn't working.

perl -n -e"/\@author / && print $'" *.java

Example input:

/* HelloWorld.java
 * @author Partner of Winning
 * @author Robert LastName
 */

public class HelloWorld{
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
mtfurlan
  • 1,024
  • 2
  • 14
  • 25
  • 3
    One difference is that `$_` ends with a newline but `$1` does not. Maybe adding `-l` to the options would help? – Jonathan Leffler Dec 04 '14 at 15:19
  • When you say "This prints nothing.", do you mean that it actually does not print anything? Because it works for me. Or did you mean that you get an error, or something else that is not "nothing". – TLP Dec 04 '14 at 15:21
  • @Jonathan: That did work. Looked up `-l`, seems to just add a newline. Tried just putting a newline on the print statement, that worked as well. – mtfurlan Dec 04 '14 at 15:24

1 Answers1

4

You must have a long prompt. A shorter prompt would have revealed the problem.

$ perl -n -e'/author (.*)/ && print $1' *.java
$ bert LastNameing

Your file has Windows line endings (carriage return + line feed), and you are outputting the carriage return without the line feed, causing lines to be overwritten.

You can convert the file to a unix file using dos2unix, or you could change your program to handle CRLF line endings. There are a couple of shortcuts you can take here.

Add newlines, effectively neutralizing the CR.

$ perl -nle'/author (.*)/ && print $1' *.java
Robert LastName
Partner of Winning

But that can output text that causes problems, since it still contains the input's CRs. The following avoids matching them:

$ perl -nle'/author ([^\r\n]*)/ && print $1' *.java
Robert LastName
Partner of Winning
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I can find not differences in the code or data, I copied both to the post, and I've copied both back to test it, yet it still prints nothing. The newlines did fix it, however. – mtfurlan Dec 04 '14 at 15:28
  • It actually has the output. If I pipe the output `command > science` and then edit the file, I can see the output, with carriage returns. But if I then `cat` that file, no output once again. – mtfurlan Dec 04 '14 at 15:35
  • Why does it do that? What's the benefit? – mtfurlan Dec 04 '14 at 15:38
  • 4
    That's what carriage returns are meant to do. They return (move to column 1) the carriage (print head). Windows uses CR+LF as line endings, but you're sending just CR to a terminal. – ikegami Dec 04 '14 at 15:42
  • 3
    `perl -e'$|=1; print "0/4"; for (1..4) { sleep 1; print "\r$_/4"; } print "\n"'` – ikegami Dec 04 '14 at 15:56