2개의 파일을 병합하고 하나의 복사본을 유지합니다.

2개의 파일을 병합하고 하나의 복사본을 유지합니다.

두 개의 입력 파일의 열을 포함하는 파일을 만들고 싶습니다.

파일 1은 다음과 같습니다.

11111111        abc12345   Y
22222222        xyz23456   Y

파일 2:

11111111       abc12345    
33333333       kbc34567

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

11111111        abc12345   Y
22222222        xyz23456   Y
33333333        kbc34567

다음을 시도하여 중복 항목을 찾을 수 있었지만 첫 번째 파일과 다른 레코드의 중복 항목도 동일한 형식(첫 번째, 두 번째 및 세 번째 열 사이의 동일한 공간)이어야 합니다.

awk 'FNR==NR{a[$1$2]=$1$2;next} ($1$2 in a) {print a[$1$2],$3}' file2 file1

답변1

i) 연결된 첫 번째 및 두 번째 필드와 ii) 세 번째 필드를 인쇄하고 있기 때문에 공백이 변경됩니다. 기본적으로 awk공백은 출력 필드 구분 기호( )로 사용되므로 공백이 OFS엉망이 됩니다. 간단한 해결책은 $0행 자체( )를 필드 대신 배열에 저장하는 것입니다.

a[$1$2]=$0;

그러나 어쨌든 스크립트는 원하는 대로 작동하지 않습니다. file2에 있는 file1의 줄만 인쇄하므로 file1에만 있는 줄은 모두 건너뜁니다. 원하는 출력에 따라 두 파일의 모든 줄을 인쇄하고, file2의 한 줄에 file1의 처음 두 필드와 동일한 처음 두 필드가 있는 경우 file1의 해당 줄만 인쇄하려고 합니다. 다음과 같은 방법으로 이 작업을 수행할 수 있습니다 awk.

awk 'FNR==NR{a[$1$2]=$0; print} !($1$2 in a) {print}' file1 file2 

file1그러면 배열의 각 행이 저장되고 인쇄됩니다. 그런 다음 file2처리 시 처음 두 필드가 없는 모든 행을 인쇄합니다 a.


다음을 사용하여 이 작업을 수행할 수도 있습니다 sort.

$ sort -uk1,2 file1 file2 
11111111    abc12345    Y
22222222    xyz23456    Y
33333333    kbc34567

두 파일 모두에서 공백의 양이 동일한지 확인하거나(예제에서는 그렇지 않음) 이를 달성하려면 다음 명령을 사용하면 됩니다.

$ sed  's/  */\t/g' file1 file2 | sort -uk1,2 
11111111    abc12345    Y
22222222    xyz23456    Y
33333333    kbc34567

답변2

파일 크기에 따라 이것이 가장 효율적인 접근 방식이 아닐 수도 있지만 특정 상황에서는 작동한다고 생각합니다. 파일이 특정 순서로 되어 있을 필요는 없지만 항상 File2보다 File1을 선호해야 합니다.

#!/bin/bash
# Make a list of the unique identifiers in each of the files, changing the whitespace in between into a comma.
awk '{print $1 "," $2}' File1 File2| sort | uniq |
# Loop through all the unique identifiers we just found
while read l; do
    # Create a regular expression for each identifier to use as
    #  a search term, changing the comma into "any number of whitespaces"
    searchterm=$(echo $l | sed 's/,/\\\s*/')
    # if this pattern exists in File1
    if $(grep -E "$searchterm" File1 >& /dev/null); then
        # print it out
        grep -E "$searchterm" File1
    else
        # otherwise, print it if it's in File2
        grep -E "$searchterm" File2
    fi
done 

File3을 원하면 스크립트로 저장하고 거기로 출력을 보낼 수 있습니다.

#copy to merge_uniq.sh
chmod +x merge_uniq.sh
merge_uniq.sh > File3

답변3

awk 'BEGIN{i=0} {if (!($1$2  in a)) {a[$1$2]=$0; index_array[i] =$1$2; i++} } END{for (j=0; j<i; j++) print a[index_array[j]]}' 1 2

11111111        abc12345   Y

22222222        xyz23456   Y
33333333       kbc34567

관련 정보