Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

This works prefectly fine for conversion of a single file. However, i am lost on how i can convert a list of files, stored in a 'list file'. Convert these files and write back to the original names in the list??
foreach $file (@ARGV) { print "Processing $file\n"; open DOIT, "| tr -s '\012\015' '\012\012' < $file > fixm_temp" or + die "*** Can't: tr '\015' '\012' < $infile > $outfile\n"; close DOIT; open DOIT, "| mv -f fixm_temp $file" or die "*** Can't: mv -f fixm_temp $file\n"; close DOIT; }

Replies are listed 'Best First'.
Re: Another dos to unix question
by Juerd (Abbot) on May 18, 2004 at 15:26 UTC

    Your perfectly working script is very scary and needlessly convoluted. But to answer your question: open a file, read its lines into an array, make sure the values are chomped and use that array instead of @ARGV (or cheat and put everything in @ARGV directly).

    I think the easiest way to do this is by using simple oneliners. Under unixish systems (where \r is always just CR), I use:

    perl -i -pe's/\r//' file file ... # do-to-unix
    and
    perl -i -pe's/$/\r/' file file ... # unix-to-dos
    Or, no, this is not the easiest way. The easiest way is to use the dos2unix and unix2dos tools.

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Re: Another dos to unix question
by monkey_boy (Priest) on May 18, 2004 at 15:52 UTC
    Maybe im missing something ...but
    On most linux/unix systems there is a program:
    dos2unix
    For doing multiple files at once
    dos2unix *
    I should really do something about this apathy ... but i just cant be bothered
Re: Another dos to unix question
by Fletch (Bishop) on May 18, 2004 at 15:22 UTC
    perl -i -pe 's/\cM*$//g' file file ...
      i am aware of the single command line stuff. But would prefer it in a script form for later use etc, thanks
        sub dos2unix { system( qq{perl -i -pe 's/\\cM*//g' $_} ) for @_ }

        (No more inefficient than opening a pipe (?!?!) to mv rather than using unlink())

        update: sorry -- I missed this part in your OP: "how i can convert a list of files, stored in a 'list file'" I have added a bit to the script to account for this. As modified, you can pipe a list of file names to the script on stdin (e.g. "ls | script.pl") or store the list(s) in some named file(s) and give the list file name(s) to the script as ARGV (e.g. "script.pl list [list2 ...]" /update.

        Well then, you could create a perl script file as follows:

        #!/usr/bin/perl # in-place dos-to-unix conversion (remove ^M's): my @file_list = <>; # update: adding these two lines to chomp @file_list; # read a list of file names for my $file ( @file_list ) { # not "@ARGV" open( I, $file ) or die "$file: $!"; open( O, ">$file.unx" ) or die "$file.unx: $!"; while (<I>) { s/\cM*//g; print O; } close I; close O; rename "$file.unx", $file or die "renaming $file.unx to $file: $!" +; }

        Note that this differs slightly from the code in your original post: your strange and less efficient approach would cause each "CRLF" sequence in a dos file to be converted to "LFLF", which means your output files would have twice as many "lines" as the originals, and half of those output lines would be empty. The version here simply removes the "CR". (Or maybe it was your intention that dos files should show up in unix as "double-spaced"?)