행의 가장 긴 공통 접두사

행의 가장 긴 공통 접두사

텍스트 파일이나 텍스트 스트림이 있는 경우 두 줄의 가장 긴 공통 접두사를 어떻게 결정하고 이를 bash의 표준 출력으로 인쇄합니까? 가장 긴 접두사가 여러 개 있는 경우 어느 것이 인쇄되는지는 상관하지 않습니다.

예를 들어 다음과 같은 입력의 경우:

abcdef
abc
defgh
abcdeg
defgi

두 줄 사이의 가장 긴 공통 접두사는 abcde(첫 번째 줄과 네 번째 줄 사이)이고, 두 번째로 긴 것은 defg, 세 번째는 abc... 입니다.

답변1

다음을 수행할 수 있습니다.

<file LC_ALL=C sort |
   sed -n 'N;h;s/^\(.*\).*\n\1.*/\1/p;g;D' |
   awk '{l = length}
        l > max {max = l; s = $0}
        END {print s}'

가장 긴 공통 접두어가 있는 행이 인접하도록 보장하는 바이트 간 비교( sortC 로케일)를 사용하여 입력을 정렬합니다.

sed우리가 인쇄한 BRE 역참조( \(.*\).*\n\1캡처된 문자 시퀀스 \(.*\)뒤에 임의 개수의 문자 .*, 개행 문자 \n및 이전에 캡처한 것과 동일한 문자 시퀀스 )를 사용하여 \1한 줄과 다음 줄 사이의 가장 긴 공통 접두사를 찾습니다 .

awk그 중 가장 긴 것을 찾습니다. (하나 이상이 있는 경우 입력의 첫 번째 항목이 선택되므로 어휘 순서의 첫 번째 항목이 됩니다. >=대신 >마지막 항목을 가져오려면 사용하세요.)

가장 긴 공통 접두사를 찾습니다.수치. 그것을 소유하다바이트, 3개 명령 모두에 대해 로 $LC_ALL설정 합니다 . 예를 들어 UTF-8 로케일에서는 와 사이의 가장 긴 공통 접두사로 2자를 찾는 대신 3바이트를 찾습니다. 성격.CsortStStéphaneStábatSt<0xc3><0xc3>áé

그것을 소유하다확장된 문자소 클러스터. 예를 들어, Steps사이 에 있지 않음 Stéphane( é두 개의 문자 문자소 클러스터로 표시됨 e\u0301) 을 찾으려면 다음을 사용할 수 있습니다 .StSteperl

<file LC_ALL=C sort |
  perl -Mopen=locale -ne '
    BEGIN{$prev = <>}
    if ("$prev$_" =~ /^(\X*).*\n\1\b{g}/) {
      $l = length($1);
      if ($l > $max) {$max = $l; $s = $1}
    }
    $prev = $_;
    END{print "$s\n"}'

( \X일치하는확장된 문자소 클러스터\b{g}그리고문자소 클러스터 경계 확장(이를 위해서는 Perl 5.22.1 이상이 필요합니다).

가장 긴 공통 접두사를 찾고 싶다면모두입력 라인(단지 임의의 라인이 아님)2입력 줄) 원래 당신이 묻는다고 생각했던 것처럼,기타 Q&A 답변은 여기에.

관련 정보