정렬되지 않은 파일과 혼합된 케이스 파일을 비교하여 고유한 항목만 선택

정렬되지 않은 파일과 혼합된 케이스 파일을 비교하여 고유한 항목만 선택

두 가지 방법으로 파일을 비교할 때 약간의 좌절감을 느낍니다.

  • 파일 1
    bill 
    telephone
    address_1
    address_2
    address_3
    city
    postal_code
    
  • 파일 2
    Bill
    Bill_ID
    Telephone
    Address_1
    Address_2
    city
    Postal_Code
    

두 개의 파일을 고유한 값으로 채우려고 합니다. 따라서 내 예상 결과는 다음과 같아야 합니다.

+-----------+---------+
|   File1   |  File2  |
+-----------+---------+
|           | Bill_ID |
| address_3 |         |
+-----------+---------+

내가 달성하려고 하는 것:

  • sdiff처음에는 사전순으로 정렬되었지만 모든 열이 생성되었습니다.

  • 또는

    sdiff -Wais File1.txt File2.txt | awk '{print $1}' | sort -u
    

    그런데 파일을 뒤집어 두 번 실행해야 합니다.

  • comm그런데 이런 오류가 있어요

    comm -23 < (sort File1.txt) <(sort File2.txt)
    bash: syntax error near unexpected token '('
    
  • diff그러나 출력이 잘못된 것 같습니다.

    diff File_1 File_2 | grep '^>' | cut -c 3-
    

이 모든 경우에 내가 직면한 문제는 단지 비교일 뿐입니다. 올바른 테이블을 계속 채울 수 없었습니다.

답변1

join조인 키로 텍스트의 소문자 버전을 사용할 수 있습니다 .

$ preprocess() { awk -v OFS='\t' '{print tolower($0), $0}' | sort -t $'\t' -k1,1; }
$ join -t $'\t' -o1.2,2.2 -v1 -v2 <(preprocess < file1) <(preprocess < file2)
address_3
        Bill_ID

답변2

게시한 입력 예에서와 같이 두 입력 파일에 동일한 단어가 여러 번 나타나지 않는다고 가정하고 모든 Unix 시스템의 모든 쉘에서 awk를 사용합니다.

$ cat tst.awk
BEGIN {
    OFS="\t"
    print ARGV[1], ARGV[2]
}
{ lc = tolower($1) }
NR==FNR {
    file1[lc] = $1
    next
}
lc in file1 {
    delete file1[lc]
    next
}
{
    print "", $1
}
END {
    for (lc in file1) {
        print file1[lc], ""
    }
}

$ awk -f tst.awk file1 file2
file1   file2
        Bill_ID
address_3

답변3

이 시도. 즉시 사용 가능한 개수에 관계없이 모든 파일을 작업할 수 있습니다.

참고 사항: space입력 데이터의 단어 끝에 있는 s에 주의하세요.

$ awk '{ str=tolower($0); a[str]++; aa[str]=$0; b[str]=b[str]" "FILENAME } 
    END{ for(i in a){ if(a[i]==1){ print aa[i],b[i] } } }' file1 file2
address_3  file1
Bill_ID  file2

테이블과 같은 출력을 원하면 전자에 awk 형식을 추가하세요. 결과를 복사하여 Excel 등에 붙여넣을 수 있습니다. 물론, 문자열의 TABs와 s는 ,형식을 망칠 것입니다.

$ awk '{ str=tolower($0); a[str]++; aa[str]=$0; b[str]=b[str]","FILENAME }
    END{ for(i in a){ if(a[i]==1){ print aa[i]b[i] } } }' file1 file2 |
  awk -F ',' '{ nm_a[$NF]++; a[$NF,nm_a[$NF]]=$1 } 
    END{ for(i in nm_a){ printf "%s\t",i; if(max<nm_a[i]){ max=nm_a[i] } }; 
    print "";  for(j=1;j<=max;j++){ for(i in nm_a){ printf "%s\t",a[i,j] } 
    print "" } }' 
file2   file1   
Bill_ID address_3

관련 정보