Reputation: 6200
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
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
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
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
Reputation: 12079
Split into groups of 30 or less, then join with newline:
$string = join("\n", ( $string =~ m/.{1,30}/g ));
Upvotes: 0
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