첫 번째 열이 반복되는 경우 가장 긴 행만 유지

첫 번째 열이 반복되는 경우 가장 긴 행만 유지

입력하다:

user@server:~/bar/foobar$ SAT=$(date -dsaturday +%Y-%m-%d); SUN=$(date -dsunday +%Y-%m-%d)
user@server:~/bar/foobar$ awk 'BEGIN {FS="'^'"} {print $1"\t"$3"\t"$6}' STs.csv STt.csv | egrep -w "${SAT}|${SUN}" | sort -u
'ST30074650'        '2015-10-17 10:00'
'ST30074650'    '[email protected]'  '2015-10-17 10:00'
'ST30085367'    '[email protected]'  '2015-10-18 13:00'
'ST30086369'        '2015-10-17 13:00'
'ST30115016'    '[email protected]'  '2015-10-18 13:00'
'ST30124587'        '2015-10-18 09:00'
'ST30123591'        '2015-10-18 09:00'
user@server:~/bar/foobar$ 

원하는 출력:

user@server:~/bar/foobar$ SAT=$(date -dsaturday +%Y-%m-%d); SUN=$(date -dsunday +%Y-%m-%d)
user@server:~/bar/foobar$ awk 'BEGIN {FS="'^'"} {print $1"\t"$3"\t"$6}' STs.csv STt.csv | egrep -w "${SAT}|${SUN}" | sort -u | SOMEMAGIC
'ST30074650'    '[email protected]'  '2015-10-17 10:00'
'ST30085367'    '[email protected]'  '2015-10-18 13:00'
'ST30086369'        '2015-10-17 13:00'
'ST30115016'    '[email protected]'  '2015-10-18 13:00'
'ST30124587'        '2015-10-18 09:00'
'ST30123591'        '2015-10-18 09:00'
user@server:~/bar/foobar$ 

질문: 따라서 첫 번째 열이 반복되는 경우(예: "ST30074650") - 더 긴 행만 유지해야 합니다. "SOMEMAGIC"의 누군가가 어떻게 이런 일을 할 수 있습니까?

답변1

나는 SOMEMAGIC이 그것과 무슨 관련이 있는지 이해하지 못합니다

이 awk 파일을 사용해 보세요

{ if ( $1 in a ) {
     if ( length(a[$1]) < length($0)) a[$1]=$0 ;
            } # $1 in a
  else  a[$1]=$0 ; }

END { for ( b in a ) {print a[b] ;}  }

사용하세요(미리 정렬할 필요 없음)

... egrep -w "${SAT}|${SUN}" | awk -f u.awk | sort

답변2

Perl 한 줄 사용:

perl -a -e '$line{$F[0]} = $_ if (length($_) > length($line{$F[0]})) ; END { foreach (sort keys %line) { print $line{$_} } };'  STs.csv STt.csv

또는 읽기 쉬운 독립형 Perl 스크립트 형식을 사용합니다.

#! /usr/bin/perl -a

$line{$F[0]} = $_ if (length($_) > length($line{$F[0]})) ;

END {
  foreach (sort keys %line) { print $line{$_} }
};

이것은 본질적으로 Archemar의 답변과 동일한 알고리즘이지만 대신 perl간단히 awk말하면 입력의 현재 줄이 배열에 대해 저장한 것보다 긴 경우 입력의 첫 번째 필드를 해시 배열의 키로 사용합니다( 기본값은 perl의 빈 문자열입니다. 현재 행이 저장됩니다. 모든 입력을 읽었으면(완료됨) 해시의 각 요소를 인쇄합니다.

답변3

user@machine:~/tmp$ cat f1
'ST30074650'    '[email protected]'  '2015-10-17 10:00'
'ST30085367'    '[email protected]'  '2015-10-18 13:00'
'ST30086369'        '2015-10-17 13:00'
'ST30115016'    '[email protected]'  '2015-10-18 13:00'
'ST30124587'        '2015-10-18 09:00'
'ST30123591'        '2015-10-18 09:00'
'ST30074650'        '2015-10-17 10:00'

user@machine:~/tmp$ sort -r f1 |uniq -w 12 |sort
'ST30074650'    '[email protected]'  '2015-10-17 10:00'
'ST30085367'    '[email protected]'  '2015-10-18 13:00'
'ST30086369'        '2015-10-17 13:00'
'ST30115016'    '[email protected]'  '2015-10-18 13:00'
'ST30123591'        '2015-10-18 09:00'
'ST30124587'        '2015-10-18 09:00'
  • 먼저 긴 행을 먼저 얻으려면 전체 행을 역순으로 정렬하십시오.
  • uniq 처음 12자만 검사하면 12자의 첫 번째(더 긴) 줄만 계속 비교됩니다.
  • 자연 정렬을 위한 선택적 최종 정렬

답변4

코드 리팩터링(원본 입력 데이터 부족으로 인해 테스트되지 않음)

awk -F '^' -v OFS='\t' \
           -v sat=$(date -d saturday +%F) \
           -v sun=$(date -d sunday +%F) \
'
    $6 !~ "^"sat && $6 !~ "^"sun {next}
    { line = $1 OFS $3 OFS $6 }
    length(line) > lines[$1] {lines[$1] = line}
    END { for (key in lines) print lines[key] }
' STs.csv STt.csv | sort

sortGNU awk를 사용하면 다음을 사용하여 후행을 생략할 수 있습니다.

    END { 
        PROCINFO["sorted_in"] = "@ind_str_asc"
        for (key in lines) print lines[key] 
    }

관련 정보