Только с zsh
:
str=foobarbazblargblurg
set -o extendedglob
printf '%s\n' ${str//(#m)????/$MATCH }
Или
printf '%s%s%s%s ' ${(s::)str}
только с ksh93
:
printf '%s\n' "${str//????/\0 }"
Только с любой оболочкой POSIX (Также избегайте завершающего пробела, если длина ввода кратна 4):
out=
while true; do
case $str in
(?????*)
new_str=${str#????}
out=$out${str%"$new_str"}' '
str=$new_str
;;
(*)
out=$out$str
break
esac
done
printf '%s\n' "$out"
Теперь это для символов . Если вы хотите сделать это, например, на графемных кластерах (, сломать Stéphane
, записанное как $'Ste\u0301phane'
, как Stép hane
, а не Ste phan e
), с помощьюzsh
:
set -o rematchpcre
str=$'Ste\u301phane' out=
while [[ $str =~ '(\X{4})(.+)' ]] {
out+="$match[1] " str=$match[2]
}
out+=$str
printf '%s\n' $out
С помощью ksh93 вы также можете разбивать по ширине отображения, что будет работать для Stéphane
выше, но также может помочь, когда используются некоторые другие виды символов нулевой -ширины или двойной -ширины :
str=$'Ste\u301phane' out=
while
start=${ printf %L.4s. "$str"; }
start=${start%.}
[ "$start" != "$str" ]
do
out+="$start " str=${str#"$start"}
done
out+=$str
printf '%s\n' "$out"