설명하다

설명하다

다음 파일이 있습니다.

AA,true
AA,false
BB,false
CC,false
BB,true
DD,true

중복 항목을 찾고 동일한 열 값을 가진 행을 제거하려고 합니다 true.

출력은 다음과 같아야 합니다.

AA,false
BB,false
CC,false
DD,true

답변1

간단한 버전:

sort input.txt | awk -F, '!a[$1]++'

"false"는 "true"보다 먼저 알파벳순으로 정렬되며 여기서 Awk 명령은 각각의 고유한 첫 번째 필드 값의 첫 번째 행만 유지합니다.

"true"는 유지하고 "false"는 유지하지 않으려면 역정렬하고 동일한 Awk 명령에 전달한 다음 다시 역정렬하세요.

답변2

awk -F, '$2 == "false" {data[$1]=$2 } $2=="true" { if ( data[$1]!="false" ) { data[$1]=$2 } } END { OFS=","; for (item in data) { print item,data[item] }}' input

설명을 위해 스크립트를 수직으로 확장합니다.

BEGIN {
   FS=","         # Set the input separator; this is what -F, does.
}
$2 == "false" {    # For any line whose second field is "false", we
   data[$1]=$2     # will use that value no matter what.
}
$2=="true" {                    # For lines whose second field is "true",
   if ( data[$1]!="false" ) {   # only keep if if we haven't yet seen a
      data[$1]=$2               # "false"
   }
}
END {                           # Now that we have tabulated our data, we
   OFS=","                      # can print it out by iterating through 
   for (item in data) {         # the array we created.
      print item,data[item]
   }
}

답변3

perl -F, -lane '
   exists $h{$F[0]} or $h[$h{$F[0]}=@h]=$_;
   $h=$_; /,false$/ or $_=$h for $h[$h{$F[0]}];
   END{ print for @h; }
' duplicates.file

데이터 구조:

  • 키는 첫 번째 필드(AAA, BBB, CCC 등)의 해시 %h이며 해당 값은 키가 발생한 순서를 알려주는 숫자입니다. 예를 들어 AAA 키 => 0, BBB 키 => 1, CCC 키 => 2입니다.
  • @h해당 요소는 인쇄 순서에 포함된 행의 배열입니다. 따라서 데이터에서 true와 false가 모두 발견되면 false 값이 배열에 저장됩니다. OTW, 데이터 유형이 있으면 존재합니다.

또 다른 방법은 GNU sed를 사용하는 것입니다.

sed -Ee '
   G
   /^([^,]*),(false|true)\n(.*\n)?\1,\2(\n|$)/ba
   /^([^,]*)(,true)\n(.*\n)?\1,false(\n|$)/ba
   /^([^,]*)(,false)\n((.*\n)?)\1,true(\n|$)/{
      s//\3\1\2\5/;h;ba
   }
   s/([^\n]*)\n(.*)$/\2\n\1/;s/^\n*//
   h;:a;$!d;g
' duplicates.file

FWIW, 위의 GNU-sed 코드에 해당하는 POSIX는 다음과 같습니다.

sed -e '
   G

   /^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2$/ba
   /^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2\n/ba

   /^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2$/ba
   /^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2\n/ba

   /^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false$/ba
   /^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false\n/ba

   /^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true$/{
      s//\3\1\2/
      h
      ba
   }
   /^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true\n/{
      s//\3\1\2\n/
      h
      ba
   }

   y/\n_/_\n/
   s/\([^_]*\)_\(.*\)$/\2_\1/;s/^_*//
   y/\n_/_\n/

   h;:a;$!d;g
' duplicates.file

설명하다

  • 이 방법에서는 인쇄할 최종 결과를 보관 공간에 저장합니다.
  • 읽은 행마다 홀드 공간을 패턴 공간에 추가하여 홀드 공간을 기준으로 현재 행의 기존 상태를 확인합니다.
  • 이제 비교 중에 5가지 일이 발생할 수 있습니다.
    • a) 현재 행은 예약된 행의 어딘가와 일치하며 false:false입니다.
      • [조치] 동일한 에러 상태가 발견되어 아무런 조치도 취하지 않습니다.
    • b) 현재 라인은 유지되는 라인의 어딘가와 일치하며 true:true입니다.
      • [조치] 이제 동일한 실제 상태가 발견되었으므로 아무것도 수행하지 마십시오.
    • c) 현재 라인은 유지 관리 라인의 어딘가와 일치하며 true:false입니다.
      • [조치] 이미 오류 상태가 존재하여 아무런 조치도 취하지 않습니다.
    • d) 현재 행은 예약된 행의 어딘가와 일치하며 false:true입니다.
      • [조치] 실제 와이어와 정확히 동일한 위치에 가짜 와이어를 교체해야 하기 때문에 약간의 작업이 필요합니다.
    • e) 현재 라인이 홀드 라인의 어떤 위치와도 일치하지 않습니다.
      • [작동] 현재 행을 끝으로 이동합니다.

결과

AA,false
BB,false
CC,false
DD,true

답변4

2단계 sort솔루션

sort -k1,1 -k2,2 -t, file | sort -k1,1 -t, -u

첫 번째 sort패스는 레코드를 필드별로 클러스터링하며 각 레코드 블록 앞의 레코드는 공통 필드 값을 공유합니다. 두 번째 패스는 필드 내의 각 고유 값에 대한 레코드를 생성하도록 설정됩니다. 안정적인 순서를 의미하므로 생성된 하나의 레코드는 필드 내의 각 고유 값에 대해 발견된 첫 번째 레코드입니다. 이는 첫 번째 패스에서 수행된 작업으로 인해 두 번째 필드의 레코드입니다.1falsetrue1sort1-u-u1falsesort

관련 정보