파일의 각 줄의 후반부를 다른 파일의 해당 부분으로 바꿉니다.

파일의 각 줄의 후반부를 다른 파일의 해당 부분으로 바꿉니다.

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

관련 정보