첫 번째 행의 첫 번째 열과 마지막 열의 값이 동일한 마지막 행의 두 번째 열을 인쇄합니다. [닫기]

첫 번째 행의 첫 번째 열과 마지막 열의 값이 동일한 마지막 행의 두 번째 열을 인쇄합니다. [닫기]

여기서 원하는 것은 공통으로 정렬된 세 번째 행이 있는 모든 행을 보고 이 행 집합을 기반으로 출력을 제공하는 것입니다. (이 테이블에는 일반적인 세 ​​번째 행 외에 다른 속성이 있지만 지금은 살펴보지 않겠습니다.) 출력을 보기 전에 이러한 행 그룹을 살펴보겠습니다. 우리가 가지고 있다면

입력하다:

0.016   0.032   1  
0.032   0.048   1  
0.048   0.064   1  
0.064   0.08    1  
0.08    0.096   1  
0.096   0.112   1  
0.112   0.128   0  
0.128   0.144   0  
0.144   0.16    0  
0.16    0.176   0  
0.176   0.192   0  
0.192   0.208   0  

이는 두 개의 행 세트가 있음을 의미합니다.

공통된 세 번째 열 값을 가지며,1

0.016   0.032   1  
0.032   0.048   1  
0.048   0.064   1  
0.064   0.08    1  
0.08    0.096   1  
0.096   0.112   1  

두 번째는 공통된 0가치를 가지고 있습니다.

0.112   0.128   0  
0.128   0.144   0  
0.144   0.16    0  
0.16    0.176   0  
0.176   0.192   0  
0.192   0.208   0

이들 각각에 대해 우리는 세 가지 값을 유지하려고 합니다.

  1. 첫 번째 행 첫 번째 열

  2. 마지막 행의 두 번째 열

  3. 공통 세 번째 열 값

이는 궁극적으로 우리에게

원하는 출력:

0.016 0.112 1  
0.112 0.208 0  

답변1

Perl이 구출하러 옵니다!

perl -ane '
    sub out { print "@_\n" }
    if ($F[2] != $three) {
        out($one, $two, $three) if defined $one;
        ($one, $three) = @F[0, 2];
    }
    $two = $F[1];
    END { out($one, $two, $three) }
    ' < input > output
  • -n입력을 한 줄씩 읽고 각 줄에 대해 코드를 실행합니다.
  • -a각 줄을 공백의 @F 배열로 나눕니다.
  • 첫 번째 행 출력을 건너뜁니다 if defined $one(세 번째 열은 이전 열과 다르지만 아직 출력할 항목이 없습니다).
  • 마지막 블록을 인쇄하려면 END 블록이 필요합니다.

답변2

나는 다음을 사용하여 그것을했다 awk:

awk 'BEGIN{f=0;OFS=" ";t=0;}  {if(f == 0 && $3 == 1) {ff=$1;f=1;next} if(f==1 && $3 == 1) {r=$2;} \
 if(t == 0 && $3 == 0) {print ff,r,1;ff=$1;t=1;next} if(t==1 && $3 == 0) {r=$2;}}  END{print ff,r,0}' file

커 보이지만 방법은 간단합니다. 마지막 열이 1인지 0인지 확인한 다음 첫 번째 행의 첫 번째 열과 마지막 행의 두 번째 열을 인쇄합니다.

더 짧은 버전:

awk 'BEGIN{f=0;OFS=" ";t=0;}  {if($3 == 1) {if(f==0){ff=$1;f=1;next} else{r=$2;}} \
else{if(t==0){print ff,r,1;ff=$1;t=1;next} else{r=$2;}}}  END{print ff,r,0}' file

처음에 f와 t의 값은 0이고, ff는 처음 $3==0으로 첫 번째 열 합계와 동일하며 f=1, 다음 행에 대해 이를 사용합니다 r=$2. 에 대해서도 마찬가지입니다 $3==0.

답변3

Perl파일을 읽고 정규식을 실행하면 됩니다 .

$ perl -0777 -pe 's/^(\H+).*\h(\d+)\n(?:.*\h\2\n)*(?:.*\h(\H+)\h+\2$)/$1 $3 $2/mg' inp.file

산출:

0.016 0.112 1
0.112 0.208 0

설명하다:

  • 전체 파일을 단일 레코드로 병합한 $_다음 정규식 작업을 수행합니다.
  • 정규식은 기본적으로 마지막 필드가 일치하는 텍스트 블록을 찾은 다음 해당 블록에서 작동합니다.
  • 3개의 정규식 부분을 통해 블록을 살펴봅니다.
    • a) 첫 번째 개행 문자에 대한 블록의 첫 번째 부분입니다.
    • b) (선택 사항) 두 번째 부분, 마지막 필드가 첫 번째 부분과 일치하는 0개 이상의 라인입니다.
    • c) 마지막 필드가 첫 번째 부분의 마지막 필드와 일치하는 세 번째 부분. 동시에 우리는 세 번째 부분의 두 번째 장면을 녹음합니다.
    • d) 이제 전체 블록을 첫 번째 부분의 첫 번째 필드로 바꾼 다음 세 번째 부분의 두 번째 필드, 첫 번째 부분의 마지막 필드로 바꿉니다.

이는 Perl위에 표시된 것과 동일한 코드이지만 명확성을 위해 별도의 주석이 삽입되어 있고 형식이 지정되었습니다.

$ perl -0777 -pe '
   s{
      ^(\H+).*\h(\d+)\n   (?#:the first row.)
      (?:.*\h\2\n)*       (?#:0 or more rows, whose last field matches the 1st row"s last.)
      (?:.*\h(\H+)\h+\2$) (?#:the  last  row, whose last field matches the 1st row"s last.)
   }{
      my($first_row_first_col, $last_row_second_col, $common_index) = ($1, $3, $2);
      join " ", $first_row_first_col, $last_row_second_col, $common_index;
   }gemx;
' inp.file

관련 정보