0

I'm currently running Strawberry Perl on WinXP, and I'm trying to process a unix-formatted flat file. The flat file uses line feed characters to delimit fields, and form feed characters to delimit a record. I am trying to convert the FF to anything else (CRLF, ';', TAB, etc). I have tried using the following perl one-liners with no success:

perl -p -e 's/\f/\r\n/g' < unix.txt > dos.txt
perl -p -e 's/\x0c/\x0d\x0a/g' < unix.txt > dos.txt
perl -p -e 's/\f/\t/g' < unix.txt > dos.txt

The only thing I've noticed is that the the dos.txt ends up with all the LF chars converted to CRLF, but the FF chars remain. I've even tried to reprocess the dos.txt file, again trying to replace the FF, but still no dice. I am still very much a perl newbie, so maybe I'm missing something? Does anyone know why the above commands don't do what I want them to do?

digital.aaron
  • 5,435
  • 2
  • 24
  • 43
  • That could be a big part of my problem right there. I just tried with double quotes, and the s/// command actually replace the FF chars! However it's still not functioning exactly how I need it to, and I think Alien Life Form's suggestions to use binmode() may be the other part of the solution. – digital.aaron Feb 01 '12 at 18:39

2 Answers2

8

The problem is that the Windows shell doesn't interpret single quotes the way the Unix shell does. You should use double quotes in your commands.

C:\ perl -e "print qq/foo\fbar/" > test.txt
C:\ type test.txt
foo♀bar
C:\ perl -pe 's/\f/__FF__/' < test.txt
foo♀bar
C:\ perl -pe "s/\f/__FF__/" < test.txt
foo__FF__bar
mob
  • 117,087
  • 18
  • 149
  • 283
  • or no quotes at all for commands with no spaces or filename wildcards. `perl -pe s/\f/__FF__/` with no quotes at all also works. – mob Feb 01 '12 at 18:34
  • How would that look using binmode with the input text file? Using the double quotes is allowing the command to actually work (replacing the pesky \f), however I'm still getting all the \n converted to \r\n. – digital.aaron Feb 01 '12 at 18:45
  • 1
    Just adding a `binmode STDOUT` call should be sufficient to cancel the `\r\n` behavior: `perl -pe "binmode STDOUT;s/\f/\n/g"` – mob Feb 01 '12 at 18:58
  • That did it! Thanks, mob! Also, thanks to Alien Life Form for the binmode() hint. – digital.aaron Feb 01 '12 at 19:05
2

You want binmode:

perldoc -f binmode
   binmode FILEHANDLE, LAYER
   binmode FILEHANDLE
           Arranges for FILEHANDLE to be read or written in "binary" or
           "text" mode on systems where the run-time libraries distinguish
           between binary and text files.  If FILEHANDLE is an expression,
           the value is taken as the name of the filehandle.  Returns true
           on success, otherwise it returns "undef" and sets $! (errno).

           On some systems (in general, DOS and Windows-based systems)
           binmode() is necessary when you're not working with a text
           file.
Alien Life Form
  • 1,884
  • 1
  • 19
  • 27
  • Binmode will prevent the conversion of `\n` to `\r\n` on windows, but it won't help with matching the `\f`. – Robert P Feb 01 '12 at 18:10
  • 1
    I'm having a hard time finding syntax examples using binmode with one-liners. What would one of my above examples look like with binmode? – digital.aaron Feb 01 '12 at 18:24