如何拆分单词的字母,每行最后四个字母?

如何拆分单词的字母,每行最后四个字母?

如何将单词的字母 和 拆分为一个空格,每行最后四个字母?例如,鉴于,

 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'

相关内容