여기서 원하는 것은 공통으로 정렬된 세 번째 행이 있는 모든 행을 보고 이 행 집합을 기반으로 출력을 제공하는 것입니다. (이 테이블에는 일반적인 세 번째 행 외에 다른 속성이 있지만 지금은 살펴보지 않겠습니다.) 출력을 보기 전에 이러한 행 그룹을 살펴보겠습니다. 우리가 가지고 있다면
입력하다:
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
이들 각각에 대해 우리는 세 가지 값을 유지하려고 합니다.
첫 번째 행 첫 번째 열
마지막 행의 두 번째 열
공통 세 번째 열 값
이는 궁극적으로 우리에게
원하는 출력:
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