Answers:
如下使用sed:
$ echo "foobarbazblargblurg" | sed 's/.\{4\}/& /g'
foob arba zbla rgbl urg
's/.\{4\}/& /g;s/ $//'
您可以使用以下简单示例:
$ echo "foobarbazblargblurg" | fold -w4 | paste -sd' ' -
foob arba zbla rgbl
sed
答案还要好。我不知道fold
之前。
fold
,它不适用于多字节字符(如echo €€€€€€€€ | fold -w4 | paste -sd' ' -
UTF-8中所示)。
这是使用grep
和的示例xargs
:
$ echo "foobarbazblargblurg" | grep -o .... | xargs
foob arba zbla rgbl
xargs
echo
默认情况下运行,因此-nen
根据echo
实现的不同,它不能与类似或包含反斜杠的单词一起使用。如果xargs运行不止一个,您也会偶尔看到奇怪的换行符echo
。最好用管道paste -sd ' ' -
代替。请注意,这-o
不是标准选项。
仅在bash中,没有外部命令:
str="foobarbazblargblurg"
[[ $str =~ ${str//?/(.)} ]]
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"
或作为单行管道版本:
echo foobarbazblargblurg |
{ IFS= read -r str; [[ $str =~ ${str//?/(.)} ]]; \
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"; }
这种工作方式是将字符串的每个字符转换为“(。)”以进行正则表达式匹配并使用捕获=~
,然后仅从BASH_REMATCH[]
数组中输出捕获的表达式 ,并根据需要进行分组。前导/尾随/中间空格已保留,请删除引号周围的内容"${BASH_REMATCH[@]:1}"
以将其忽略。
在这里,它包装在一个函数中,该函数将处理其参数或在没有参数的情况下读取stdin:
function fmt4() {
while IFS= read -r str; do
[[ $str =~ ${str//?/(.)} ]]
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"
done < <( (( $# )) && printf '%s\n' "$@" || printf '%s\n' $(< /dev/stdin) )
}
$ echo foobarbazblargblurg | fmt4
foob arba zbla rgbl urg
您可以轻松地参数化计数以相应地调整格式字符串。
添加了尾随空格,printf
如果有问题,请使用2 而不是1:
printf "%s%s%s%s" "${BASH_REMATCH[@]:1:4}"
(( ${#BASH_REMATCH[@]} > 5 )) && printf " %s%s%s%s" "${BASH_REMATCH[@]:5}"
第一个printf
打印(最多)前4个字符,第二个有条件地打印所有其余字符(如果有的话),并用前导空格分隔各组。测试是针对5个元素而不是4个元素来说明第零个元素。
笔记:
printf
的%c
可被用来代替%s
,%c
(也许)使得意图清晰,但它不是多字节字符安全。如果您的bash版本能够使用,则以上内容都是多字节字符安全的。printf
重用其格式字符串,直到用完所有参数为止,因此它一次吞噬了4个参数,并处理了尾随参数(因此不需要边缘情况,这与其他一些可能是错误的答案不同)BASH_REMATCH[0]
是整个匹配的字符串,因此仅从索引1开始的输出printf -v myvar ...
存储到变量中myvar
(取决于常规的读取循环/子shell行为)printf "\n"
如果需要添加您可以在上面工作zsh
,如果你使用数组match[]
来代替BASH_REMATCH[]
,并从所有索引减1为zsh
不保持0元素与整场比赛。
与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 shell(如果输入长度是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"
现在,这是针对角色的。如果要在字素簇上执行此操作(例如,break Stéphane
,写为$'Ste\u0301phane'
,as Stép hane
和not 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"
我将通过仅按要求插入空格来回答问题,这样一行上至少每4个字符之后就会出现一个空格。不确定要使用哪种方式处理此案。例如,给定输入“ aa bbccdd”,您将获得输出“ aa bbcc dd”而不是“ aa b bccd d”。
我正在使用Perl进行前瞻,但总体上我对Perl不太熟悉,因此可能需要进行一些调整:
$ echo "foobarbazblargblurg" | perl -wp -e 's/[^ ]{4}(?=[^\n ])/$& /g'
foob arba zbla rgbl urg
$ echo 'aa bbccdd' | perl -wp -e 's/[^ ]{4}(?=[^\n ])/$& /g'
aa bbcc dd
# not 'aa b bccd d'!
$ echo 'some input' | perl -wp -e 's/[^ ]{4}(?=[^\n ])/$& /g'
some inpu t
# not 'some inp ut'!
$ echo $'aabb\nc cddee' | perl -wp -e 's/[^ ]{4}(?=[^\n ])/$& /g' |
> while read; do echo "${REPLY}x"; done
aabbx
c cdde ex
# no spaces added at the end of the first line (while loop to add to the end of
# the line and show this)
我已经通过使用python做到了
首先,我正在读取文件,然后将其除以4个字符并添加空格
#!/usr/bin/python
import re
b=re.compile(r'[a-z]{4}')
p=open('/root/l.txt','r')
i=p.readlines()
for j in i:
m=re.findall(b,j)
print " " .join (m) + " "
/root/l.txt ==>包含您在示例中给出的内容
输出
foob arba zbla rgbl
sed
我首先尝试的自己可以踢自己。