I have a long string like: "1 2 6 9 18 19 25 67 89 102 140 187" and I want to fold or wrap it after a specified number of inputs or spaces using (e.g. fold on the third input) rather an the number of characters, which varies.
3 Answers
The simplest answer probably is:
echo "1 2 6 9 18 19 25 67 89 102 140 187 99 12" | xargs -n 3
-
1
-
1
Here's a perl script that folds stdin on words (i.e. strings separated by spaces). You specify the number of "words" on the command line.
Save it as, e.g., fold-words.pl and make it executable with chmod +x fold-words.pl
#! /usr/bin/perl
use strict;
my $max = shift ;
while (<>) {
my $count = 0;
foreach my $word (split) {
print "$word " ;
$count++ ;
print "\n" if ($count % $max == 0)
}
print "\n" if ($count % $max != 0);
$count=0;
}
Example output:
$ echo "1 2 6 9 18 19 25 67 89 102 140 187 99 12" | ./fold-words.pl 3
1 2 6
9 18 19
25 67 89
102 140 187
99 12
Note that it's possible to have a more stringent (or even bizarre) definition of "words" by changing the (split)
to use any arbitrary regular expression. e.g. (split /\t/)
will split only on single tabs, rather than the default of "one or more white space characters".
-
@Jon see the improved version. It fixes a bug (not printing a newline if there weren't a multiple of $max words printed for that input line).– casNov 8, 2015 at 0:03
Here's a simple awk version; change the 3 in %3
if you want a different number of fields per line:
awk '{ for(i=1; i<NF; i++) { printf $i OFS; if (i%3 == 0) { print "" }} printf $i}'
Sample run:
$ str="one two three four five"
$ echo $str | awk '{ for(i=1; i<NF; i++) { printf $i OFS; if (i%3 == 0) { print "" }} printf $i}'
one two three
four five