Reputation: 138286
Is there a *nix command that formats input (delimited by newlines) so that only a specific max number of elements appear per line? For example:
$ yes x | head -10 | command 4 x x x x x x x x x x
I wrote a quick bash
script (shown below) that performs this task, but it seems long and probably inefficient. Is there a better way to do this?
#!/bin/sh
if [ -z "$1" -o -z "$2" ]; then
echo Usage `basename $0` {rows} {columns}
exit 1
fi
ROWS=$1
COLS=$2
input=$(yes x | head -${ROWS})
lines=()
i=0
j=0
eol=0
for x in ${input[*]}
do
lines[$i]="${lines[$i]} $x"
j=`expr $j + 1`
eol=0
if [ $j -ge ${COLS} ]; then
echo lines[$i] = ${lines[$i]}
i=`expr $i + 1`
j=0
eol=1
fi
done
if [ ${eol} -eq 0 ]; then
echo lines[$i] = ${lines[$i]}
fi
Upvotes: 4
Views: 7970
Reputation: 27218
You can use xargs(1) for this, with the -n
or --max-args=
option to limit the number of arguments per command line:
$ yes x | head -10 | xargs -n4
x x x x
x x x x
x x
$
Obviously, you have to be able to trust the input; for example, xargs famously breaks if the quotes are not matched:
$ yes 'x"' | head -10 | xargs -n4
xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option
$
Upvotes: -1
Reputation: 9349
why dont you try something like
sed 's|\(.{10}\)|\1\n|'
I'working on Window machine and have not tried this.My idea is just match everything for N number of times and replace them with matched pattern plus new line character.
P.S Please correct the sed expression for any syntatic fault.
Upvotes: 0
Reputation: 360105
printf '%-10s%-10s%-10s%s\n' $(command | command)
printf
will consume the number of arguments specified in the format string at a time and continue until they're all consumed.
Demonstration:
$ printf '%-10s%-10s%-10s%s\n' $(yes x | head -n 10)
x x x x
x x x x
x x
$ printf '%-10s%-10s%-10s%s\n' $(<speech)
now is the time
for all good men
to come to the
aid of their country
Upvotes: 5
Reputation: 50185
yes x | head -10 | awk 'BEGIN { RS = "%%%%%%%" } { split($0,a,"\n"); for (i=1; i<length(a); i+=4) print a[i], a[i+1], a[i+2], a[i+3] }'
More readable:
yes x | \
head -10 | \
awk 'BEGIN { RS = "%%%%%%%" }
{ split($0,a,"\n");
for (i=1; i<length(a); i+=4) print a[i], a[i+1], a[i+2], a[i+3] }'
Upvotes: 1
Reputation: 798676
Arrays can be sliced.
$ foo=(q w e r t y u)
$ echo "${foo[@]:0:4}"
q w e r
Upvotes: 8