단어의 글자, 즉 각 줄의 마지막 네 글자를 어떻게 분할하나요?

단어의 글자, 즉 각 줄의 마지막 네 글자를 어떻게 분할하나요?

단어의 글자 합을 공백과 각 줄의 마지막 네 글자로 나누는 방법은 무엇입니까? 예를 들어, 주어진

 1. placing
 2. backtick
 3. paragraphs

아래 보고싶다

 1. pla cing
 2. back tick
 3. pa ragr aphs

답변1

해결책:

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:]]이를 앤 루프로 바꿉니다. 마지막으로 마커를 제거했습니다.[^[: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주어진 단어(실제로는 포함된 전체 입력 줄)가 반전됩니다.
  • 정규식은 반대의 단어를 4개의 문자 덩어리로 나눕니다(원래 단어의 시작 부분에서 시작하는 마지막 덩어리에는 더 적은 문자가 포함될 수 있습니다).
  • join이 청크를 문자열로 연결하지만 그 사이에 공백이 있습니다 .
  • reverse연결된 문자열을 외부 적으로 반전시킵니다.
  • 스칼라 컨텍스트에서 scalar외부를 강제로 실행하는 데 사용됩니다 .reverse
  • 결과가 출력 됩니다 print.

아래 코드는 동일한 작업을 수행하지만 을 취소 scalar하고 "\n"print사용하며 -p다음 -l에 할당합니다 $_.

perl -lpe '$_ = reverse join " ", reverse =~ /.{1,4}/g'

관련 정보