R의 솔루션

R의 솔루션

#'100개 이상의 열이 있는 경우 블록의 일부( #'( )로 시작하는 줄)를 구성할 때 코드 줄을 끊(추가) 하고 싶습니다 .#\x27

내 솔루션이 여러 블록에서 작동하지 않습니다.

예시 파일:

#' chunk line
#' big chunk line to split big chunk line to split big chunk line to split big chunk line to split big chunk line to split
#' ruler90123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
#'
not chunk line do nothing

big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line

#' chunk line
#' big chunk line to split big chunk line to split big chunk line to split big chunk line to split big chunk line to split
#' ruler90123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
#'
not chunk line do nothing

big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line

내 시도: (블록이 하나만 존재하는 경우 작동함)

perl -0777 -pe '
  s{#\x27.*#\x27}{                          q{ gets lines from #\x27 to #\x27 (chunk) };
    ($r = $&) =~ s/\n!\n#\x27//g;           q{ removes breaks except followed by #\x27 }; 
    $r =~ s/\G.{0,100}(\s|.$)\K/\n#\x27 /g; q{ before column 100 adds break + #\x27 };
    $r =~ s/#\x27 #\x27/#\x27/g;            q{ removes duplicated #\x27 };
    $r =~ s/\n\n/\n/g;                      q{ removes duplicated breaks };
    $r
  }gse' < chunks.txt

예상 출력: (2번)

#' chunk line
#' big chunk line to split big chunk line to split big chunk line to split big chunk line to split
#' big chunk line to split
#' ruler90123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
#'
not chunk line do nothing

big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line big do nothing line

R의 솔루션

psum <- function(...,na.rm=FALSE) {
  rowSums(do.call(cbind,list(...)),na.rm=na.rm)
}    

gblines<-readLines("chunks.txt")

newgblines<-character()
i<-1
j<-1
repeat {
  newgblines[j] <- gblines[i]
    if (grepl("^#\'",newgblines[j] ) & nchar( newgblines[j] ) > 100 ) { # select lines with more than 100 and beginning in #'
      repeat{
        greps<-gregexpr(pattern ="\\s",newgblines[j])[[1]] # get position of spaces
        lenG<-length(greps)
        sums<-psum(-greps , rep(100,lenG ) )               # calculate which space is closest to col. 100
        index <- which(sums>0)
        minSums<- min(sums[index])
        index2<-which(sums==minSums)                       # index of space in greps
        cutpoint<-greps[index2]
        nchar2<-nchar(newgblines[j])                       # number of chars. in line
        strFirst <-substr(newgblines[j],1,cutpoint)        # cut before col. 100
        strSecond<-substr(newgblines[j],cutpoint+1,nchar2) # segmente after col. 100
        newgblines[j]<-strFirst
        j<-j+1
        newgblines[j]<-paste0("#\' ",strSecond)
        if (nchar(strSecond)<=100 ){
          break
        }
      } # 
    } #  if
  i <- i+1
  j <- j+1
  if (i>length(gblines) ){
    break
  }
}
newgblines

답변1

거의 다 왔습니다.

다음 두 가지 사항을 변경합니다.

  • 변화
    s{#\x27.*#\x27}{
    
    도착하다
    s{#\x27.*?#\x27$}{
    
  • 그리고 변화
    }gse' < fileName
    
    도착하다
    }mesg' < fileName
    

기본적으로 탐욕스러운 검색 및 교체를 수행하고 있습니다. 대신 필요한 것은 블록 지향 검색 및 교체 작업입니다.

#' 오른쪽에 개행 문자가 보이는 마커를 사용하면 블록의 끝이고 정규식은 .*?탐욕스럽지 않은 버전입니다..*

자세한 내용은 다음을 참조하세요.펄 문서

답변2

#'으로 끝나는 블록을 사용하지 않는 대체 일반 답변 완벽하지는 않지만 더 잘 작동합니다.

perl -0777 -pe '
q{ 4 manual entries };
  $max_length = 100;
  $line_filter_pattern = "#\x27 ";                  
  $prefix_pattern = "#\x27 ";         
  $break_point = " ";                               q{ character in which to break lines };
  
  $linebreak_prefix = "\n$prefix_pattern";          q{ \n is linebreak };
  $lp_length = length($linebreak_prefix);

q{act in lines with prefix pattern };

  s{$line_filter_pattern.*?$}{
    ($r2 = $r = $&);

q{    check if splitting makes changes };
      $r2 =~ s/\G.{0,$max_length}($break_point|.$)\K/$linebreak_prefix/gs;
      if(length($r2) > length($r) + $lp_length) {

q{      add breaks and prefixes in a loop way };
        $r = $r2;
        $r =~ s/$linebreak_prefix$//g;
      }
  $r }gsem' < input.file > output.file

관련 정보