1

I have this code to create a list of .txt files inside of a dir, and print it in 2 columns in a output file; so I just want to avoid the new line (\n) after of the last file

#!/usr/bin/perl -w
use strict;
use Getopt::Long;


#Variables
my ($dir_path, $outputfile);

GetOptions (
            'dir=s'      =>\$dir_path,
            'list=s'      =>\$outputfile
            );

opendir (DIR, $dir_path) or die $!;

open LIST, '>', $outputfile, or die "can´t open $outputfile file";

while (my $files=readdir(DIR)) {
    chomp $files;

    if ($files =~ m/\.txt$/g) {
        print LIST "$files\t$files\n";
    }
    else {
        next;
    }
}

closedir DIR;
close LIST;
exit;

it print:

file_1.txt file_1.txt
file_2.txt file_2.txt
file_3.txt file_3.txt
file_Last.txt file_Last.txt
NEW_LINE (\n)

and I just want to avoid print the las NEW LINE after of the last file !!!:

file_1.txt file_1.txt
file_2.txt file_2.txt
file_3.txt file_3.txt
file_Last.txt file_Last.txt
abraham
  • 661
  • 8
  • 14
  • 1
    I see absolutely no way for the code you show to print what you show as printed. Can you check what you posted, the code and what it prints? Or ... do you mean by `NEW_LINE (\n)` to say that there is an extra blank line at the end of the file? – zdim Dec 06 '18 at 19:56
  • Tip: `if ($files =~ m/\.txt$/g)` makes no sense and can cause weird, hard-to-debug errors. It should be `if ($files =~ m/\.txt$/)` – ikegami Dec 07 '18 at 19:56
  • 1
    Your request is very weird!!! Every line including the last one should have a terminating line feed – ikegami Dec 07 '18 at 19:57

3 Answers3

7

If you are open to an alternate approach, you could just read all files into an array and then print them with a join:

my @files = grep { /\.txt$/ } readdir (DIR);
print LIST join "\n", map { "$_\t$_" } @files;

This can be golfed down quite a bit, but I thought this would show the steps clearly enough.

By the way, best practice dictates you should change the filehandles DIR and LIST to $DIR and $LIST.

Which one is good practice, a lexical filehandle or a typeglob?

Why is three-argument open calls with autovivified filehandles a Perl best practice?

Hambone
  • 15,600
  • 8
  • 46
  • 69
2

Requisite plug for IO::All:

perl -MIO::All -E 'say for io->dir("~/Documents/")->glob("*.txt")'

Or, as a script instead of a one-liner:

use IO::All;
my @dir = io->dir("~/Documents/")->glob("*.txt");
print join "\n", @dir ;

Sorry :-)

zdim
  • 64,580
  • 5
  • 52
  • 81
G. Cito
  • 6,210
  • 3
  • 29
  • 42
0

Instead of reading all the lines into memory and joining them, you can approach this by changing the problem from "add a newline to the end of each line except for the last" to "add a newline to the beginning of each line except for the first". The second problem is much easier to solve.

Working example to illustrate the concept:

use strict;
use warnings;

# a set of chomp-ed "lines" to print
my @lines = qw(foo bar baz);

# newline before each line (but blank for the first line)
my $nl = '';

# print the lines with \n before all except first
for (@lines) {
  print "$nl$_";
  # remaining lines will get \n before them
  $nl = "\n";
}
showaltb
  • 958
  • 4
  • 12