A, B 두 개의 파일이 있습니다. 두 파일의 각 줄은 항목으로 간주됩니다. 각 항목의 형식은 고정되어 있으며 공백으로 구분된 키와 설명으로 구성됩니다. 다음 예에 표시된 대로입니다.
UASCH-XCF02-SP062 /users/documents/ark
첫 번째 부분 UASCH-XCF02-SP062
이 요점이고 마지막 부분이 /users/documents/ark
설명입니다. 파일 A와 B에는 각각 1000개와 100000개의 항목이 있습니다. 동일한 파일의 각 키는 고유하지만 파일 A의 항목에 대한 키는 파일 B에도 나타나지만 설명이 다릅니다. 다음의 간단한 예에서 볼 수 있습니다.
파일 A
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
문서 B
UASCH-XCF02-SP062 /users/documents/ark3
UASCH-XXF02-SP063 /users/documents/ark4
UASCH-XXF03-SP064 /users/documents/ark5
파일 B의 동일한 키에 해당하는 설명을 파일 A의 키에 해당하는 설명으로 바꾸고 싶습니다. 예제의 결과는 아래와 같습니다.
문서 B
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5
이 목표를 달성하는 방법은 무엇입니까?
답변1
이는 AWK를 사용하여 수행할 수 있습니다.
$ awk 'NR==FNR{a[$1]=$2;next} $1 in a {$2=a[$1]} 1' A.txt B.txt
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5
편집: Ed의 의견으로 인해 AWK 표현식의 후반부를 단순화했습니다.
파일 B를 편집하려면 다음과 같이 AWK 출력을 임시 파일로 리디렉션하고 파일 B를 해당 파일로 바꿉니다.
awk 'NR==FNR{a[$1]=$2;next} $1 in a {$2=a[$1]} 1' A.txt B.txt >B.txt.tmp
mv B.txt.tmp B.tmp
작동 방식. 먼저 NR==FNR
첫 번째 파일과 두 번째 파일을 구별하는 관용구를 사용하여 첫 번째 파일(A)의 모든 키-값 쌍을 연관 배열에 저장합니다 . 그런 다음 두 번째 파일(B)을 반복할 때 현재 키가 첫 번째 파일에 있는지 확인하고, 그렇다면 현재 값을 첫 번째 파일에서 찾은 값으로 바꿉니다.
답변2
순전히 bash
... bash
쉘이라면 내장된 쉘만 사용하여 이 작업을 수행할 수 있으며 외부 유틸리티/명령은 필요하지 않습니다... 그러나 어떤 경우에는 전용 텍스트 처리 도구보다 느릴 수 있습니다. 약간, 그럼에도 불구하고, 아는 것이 도움이 됩니다.
array
다음과 같이 연관 배열을 선언하십시오.
declare -A array
A
그런 다음 공백, 즉 다음과 같은 내부 필드 구분 기호를 사용하여 파일을 읽습니다 .
while IFS=' ' read -r k v
do
array[$k]="$v"
done < A
그런 다음 파일 B
라인을 읽고, 키를 비교하고, 값을 바꾸고, 최종 결과를 다음과 같이 인쇄합니다.
while IFS=' ' read -r k v
do
if [[ "${!array[*]}" =~ "$k" ]]
then
printf '%s %s\n' "$k" "${array[$k]}"
else
printf '%s %s\n' "$k" "$v"
fi
done < B
그러면 다음이 출력됩니다.
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5
알아채다: 처럼배쉬 배열1차원적이므로 위의 접근 방식은 사용 사례에 적합합니다(즉하나열쇠와하나값)과 유사하지만 각 추가 값을 별도의 토큰으로 구문 분석해야 하는 경우 여러 값이 있는 키에는 작동하지 않습니다.
답변3
정렬은 고정되어 있으며 'uniq'는 처음 N 문자만 고려할 수 있으므로...
고양이 AB | 정렬 | uniq -w 17 > /tmp/foo ;
예 - 예상대로 작동합니다
$ cat A B | sort | uniq -w 17
UASCH-XCF02-SP062 /users/documents/ark1
UASCH-XXF02-SP063 /users/documents/ark2
UASCH-XXF03-SP064 /users/documents/ark5