如何将单词的字母 和 拆分为一个空格,每行最后四个字母?例如,鉴于,
1. placing
2. backtick
3. paragraphs
我想在下面看到
1. pla cing
2. back tick
3. pa ragr aphs
答案1
awk解决方案:
awk '{ c=0; for(i=length($2);i>0;i-=4) {a[++c]=(i-4>0)? substr($2,i-4+1,4) : substr($2,1,i)}
$2=""; for(i=length(a);i>0;i--) $2=$2 FS a[i] }1' file
输出:
1. pla cing
2. back tick
3. pa ragr aphs
答案2
通过Perl
使用lookarounds
我们可以执行以下操作:
perl -pe 's/(?<=\w)(?=(?:\w{4})+$)/ /g'
这意味着:当站在某个位置时,我们的左边是一个字母数字,右边是至少 4 个数字或其倍数,一直到字符串的末尾。只要存在这样的位置,就会在那里放置一个空间。这样做会全局影响所请求的更改。
我们也可以bash
这样做:
#!/bin/bash
# symbolic constants
NL=$'\012'; # newline
SP=$'\040'; # space
# elementary regexes
alnum='[0-9a-zA-Z]'; # a single alphanumeric
alnums4=$(csh -c 'repeat 4 echo -n "$1"' "$alnum"); # 4 consecutive alnums
# main processing
while IFS= read -r line res; do
while c4=$(expr "$SP$line$NL" : ".*$alnum\($alnums4\)$NL")
do
res=${c4}${res:+"$SP"}${res-} line=${line%????}
done
printf '%s %s\n' "$line" "$res"
done
使用GNU sed
编辑器:
sed -Ee '
s/\S+/\n&\n/2; # enclose the 2nd field with markers
# a do-while loop to progessively move the right marker to the left,
# consuming 4 alnums in each iteration. Looping stops when 4 alnums+
# 1 alnum at the boundary remains.
:loop
s/(\n[[:alnum:]].*)([[:alnum:]]{4})\n/\1\n \2/
tloop
# clear out the markers when done
s/\n//g
'
答案3
使用sed
,您可以执行以下操作:
sed '
G
:1
s/\([[:alpha:]]\)\([[:alpha:]]\{4\}\)\(\n\)/\1\3 \2/
t1
s/\n//
'
我们使用换行符作为运行标记(换行符是不会出现在初始模式空间内的一个字符)。我们最初将其添加在末尾。然后只要我们找到ABCDE<marker>
(其中ABCDE是5个字母字符,如果你想将单词视为非空格序列而不是字母序列,你可以替换[[:space:]]
为),我们将其替换为and循环。最后我们删除了标记。[^[:blank:]]
A<marker> BCDE
这样,我们就可以确保只处理行尾的单词。
如果你想分解每个单词,而不仅仅是最后一个单词,那就更简单了:
sed -e :1 -e 's/\(.*[[:alpha:]]\)\([[:alpha:]]\{4\}\)/\1 \2/;t1'
printf 'abcd\u00e9e\u0301f\n'
如果您的输入包含分解的字符(如:的输出abcdééf
),您可以这样做:
perl -Mopen=locale -lpe 'while(s/.*(?=\w)\X\K(?:(?=\w)\X){4}/ $&/){}'
答案4
使用 Perl(并假设仅使用单字节字符):
perl -ne 'print scalar(reverse join " ", (reverse =~ /.{1,4}/g)), "\n"'
- 内部
reverse
将反转给定的单词(实际上,整个输入行,无论它包含什么)。 - 正则表达式会将反转的单词分成四个字符的块(最后一个块,从原始单词的开头开始,可能包含更少的字符)。
- 会将
join
这些块连接成一个字符串,但中间有空格。 - 外部
reverse
反转连接的字符串。 - 用于
scalar
强制外部reverse
在标量上下文中运行。 - 将
print
输出结果。
下面的代码做了同样的事情,但取消了scalar
,"\n"
并print
使用-p
,-l
并分配给$_
:
perl -lpe '$_ = reverse join " ", reverse =~ /.{1,4}/g'