0

I have tried

declare -a arr=( {A..Y} )
for j in {06..10}; do
        echo -n "$j "
        for (( i=0; i<25; i++ )); do
                if [ $i -eq 4 ]; then
                        echo -n "${arr[$i]}${arr[$i]}"
                        break
                else
                        echo -n "${arr[$i]}${arr[$i]}"
                        echo -n " "
                fi
        done
        echo
done

but I get enter image description here

Also tried

declare -a arr=( {A..Y} )
for j in {06..10}; do
        echo -n "$j "
        for (( i=0; i<25; i++ )); do
                echo -n "${arr[$i]}"
                echo -n " "
        done
        echo
done

But I get enter image description here

Thank you

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108

4 Answers4

3

You can use a bash array slice:

declare -a arr=( {A..Y} )
n=5
for ((i = 0; i < ${#arr[@]}; i = i + n))
do
    echo "${arr[@]:i:n}"
done
A B C D E
F G H I J
K L M N O
P Q R S T
U V W X Y
Fravadona
  • 13,917
  • 1
  • 23
  • 35
2

Alternate method using common 'nix tools and no shell loop:

#!/usr/bin/env bash
printf '%s %s %s %s %s\n' {A..Y} | nl -nrz -s' ' -v6 -w2

Explanations:

  • printf '%s %s %s %s %s\n' {A..Y}: Prints formatted 5 string arguments %s separated by a space and ending with a new-line \n.

    As the printf consumes only 5 arguments at a time out of the 25 generated by the Bash's bracket expression {A..Y}, the format will be applied to each group of 5 arguments, resulting in this output:

    A B C D E
    F G H I J
    K L M N O
    P Q R S T
    U V W X Y
    
  • | nl -nrz -s' ' -v6 -w2: Streams the above to the nl command to add line numbers.

    • -nrz: Formats numbers right-aligned with zero padding.

    • -s' ': separates numbering from text with a blank  .

    • -v6: Starts numbering at 6.

    • -w2: Number width 2.

Final result:

06 A B C D E
07 F G H I J
08 K L M N O
09 P Q R S T
10 U V W X Y
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
1

I think it's simpler if you keep a separate variable to count how many you've printed already and print a newline when you've printed 6 characters.

Example:

#!/bin/bash

declare -a arr=( {A..Y} )

count=0;
for ch in "${arr[@]}"
do
    echo -n "$ch "

    (( count = (count + 1) % 5 ))

    if (( count == 0 )) ; then
        # 6 characters printed, now print a newline
        echo
    fi
done

An alternative using an index variable in the loop instead:

for ((idx = 0; idx < ${#arr[@]}; ++idx)); do
    echo -n "${arr[$idx]} "

    if (( (idx+1) % 5 == 0 )); then
        echo
    fi
done

Both output:

A B C D E
F G H I J
K L M N O
P Q R S T
U V W X Y

If you want 06...10 to be printed first on each line:

step=5
for ((idx = 0; idx < ${#arr[@]}; ++idx)); do
    if (( (idx) % step == 0 )); then
        (( pre = idx/step + 6 ))
        printf "%02d " "$pre"
    fi

    echo -n "${arr[$idx]} "

    if (( (idx+1) % step == 0 )); then
        echo
    fi
done

Or simpler

step=5
for ((idx = 0; idx < ${#arr[@]}; idx += step)); do
    (( pre = idx/step + 6 ))
    printf "%02d " "$pre"
    echo  "${arr[@]:idx:step}"
done

Output:

06 A B C D E
07 F G H I J
08 K L M N O
09 P Q R S T
10 U V W X Y
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
1

Also

printf '%s\n' {A..Y} | paste -d ' ' - - - - -

Or with plain bash

alphabet=({A..Y})
for i in "${!alphabet[@]}"; do
    ((i % 5 == 4)) && sep=$'\n' || sep=' '
    printf '%s%s' "${alphabet[i]}" "$sep"
done
glenn jackman
  • 238,783
  • 38
  • 220
  • 352