user1701545
user1701545

Reputation: 6200

Print fixed number of characters per line in perl

Suppose I have a string of length 160 characters and I want to print it out to a file with 30 characters per line (so the 5 first line in the output will have 30 characters and the last line will have 10 characters).

Is there a straight forward perl command for that?

Upvotes: 0

Views: 1988

Answers (5)

Kaoru
Kaoru

Reputation: 1570

There's more than one way to do it! :-)

For this task I would reach for Perl6::Form, a very powerful text formatting library. The Perl6 namespace implies that it's a back-port of a Perl 6 feature to Perl 5.

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

use Perl6::Form;

my $s = join('', 'A' .. 'J') x 16;

say form "{" . ("[" x 30) . "}", $s;

This outputs:

$ ./line-breaks.pl
ABCDEFGHIJABCDEFGHIJABCDEFGHIJA-
BCDEFGHIJABCDEFGHIJABCDEFGHIJAB-
CDEFGHIJABCDEFGHIJABCDEFGHIJABC-
DEFGHIJABCDEFGHIJABCDEFGHIJABCD-
EFGHIJABCDEFGHIJABCDEFGHIJABCDE-
FGHIJ

Note the "-" characters on the end of each line. This shows that Perl6::Form actually handles word breaking unlike the unpack()- or m//g-based solutions.

For example if we give it some text with spaces in it we can see it is left-aligned, with a ragged right edge.

$ ./line-breaks.pl
Lorem ipsum dolor sit amet,
consectetur adipisicing elit,
sed do eiusmod tempor incididunt
ut...

If you change the 30 "[" characters to 15 "[" characters followed by 15 "]" characters then you get fully justified output.

$ ./line-breaks.pl
Lorem  ipsum  dolor  sit   amet,
consectetur  adipisicing   elit,
sed do eiusmod tempor incididunt
ut...

Like I said, Perl6::Form is very powerful :-)

You will need to install it, either via CPAN (/usr/bin/cpan) or your OS' package manager. On Debian you can install Perl6::Form system-wide with sudo apt-get install libperl6-form-perl.

Upvotes: 0

Borodin
Borodin

Reputation: 126722

This is clearer and more concise using unpack

my $s = join('', 'A' .. 'J') x 16;

print "$_\n" for unpack '(A30)*', $s;

output

ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
ABCDEFGHIJABCDEFGHIJABCDEFGHIJ
ABCDEFGHIJ

Upvotes: 4

mpapec
mpapec

Reputation: 50647

You can insert newlines every 30 chars,

$string =~ s/.{1,30}\K/\n/sg;

or using variation of @Miller solution,

while ($string =~ m/(.{1,30})/gs) {
  print $1, "\n";
}

Upvotes: 3

bloodyKnuckles
bloodyKnuckles

Reputation: 12079

Split into groups of 30 or less, then join with newline:

$string = join("\n", ( $string =~ m/.{1,30}/g ));

Upvotes: 0

Miller
Miller

Reputation: 35198

Use a regex, taking advantage of greedy matching:

my $string = 'a' x 160;

for my $buffer ($string =~ m/.{1,30}/gs) {
    print $buffer, "\n";
}

Outputs:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaa

Upvotes: 1

Related Questions