유닉스의 vlookup 함수

유닉스의 vlookup 함수

Unix에서 Excel의 vlookup 기능과 유사한 기능을 어떻게 만들 수 있나요?

사무실 홈페이지에서 발췌,조회 테이블

VLOOKUP의 V는 수직을 의미합니다. 비교 값이 찾고 있는 데이터 왼쪽 열에 있는 경우 HLOOKUP 대신 VLOOKUP을 사용하세요.

구문 VLOOKUP(lookup_value,table_array,col_index_num,range_lookup)

Lookup_value 테이블 배열의 첫 번째 열에서 검색할 값입니다. Lookup_value는 값 또는 참조일 수 있습니다. lookup_value가 table_array의 첫 번째 열에 있는 가장 작은 값보다 작은 경우 VLOOKUP은 #N/A 오류 값을 반환합니다.

Table_array 두 개 이상의 데이터 열입니다. 범위 또는 범위 이름에 대한 참조를 사용하십시오. table_array의 첫 번째 열의 값은 lookup_value로 검색한 값입니다. 이러한 값은 텍스트, 숫자 또는 논리값일 수 있습니다. 대문자와 소문자 텍스트는 동일합니다.

Col_index_num 일치하는 값을 반환해야 하는 table_array의 열 번호입니다. col_index_num이 1이면 table_array의 첫 번째 열 값이 반환되고, col_index_num이 2이면 table_array의 두 번째 열 값이 반환되는 식입니다. col_index_num이 다음과 같은 경우:

1보다 작으면 VLOOKUP이 #VALUE를 반환합니다! 차이점. table_array의 열 수보다 크면 VLOOKUP은 #REF를 반환합니다! 차이점.

Range_lookup VLOOKUP이 정확한 일치 또는 대략적인 일치를 찾을지 여부를 지정하는 논리 값입니다.

파일 1:

1GR_P1:001PI
:040VG_L1
:001PO_L3
1JPI_P1:001PO_L1
1JPI_P1:001PO_L2

파일 2:

1JPI_P1:001PO_L1    1401UC
1JPI_P1:001PO_L2    1401UC
1HIK_P2:001ER       1402UC
1GR_P1:001PI        1402UC

출력 파일 3:

1GR_P1:001PI        1402UC
:040VG_L1       NA
:001PO_L3       NA
1JPI_P1:001PO_L1    1401UC
1JPI_P1:001PO_L2    1401UC

답변1

vlookupUnix의 범용 함수와 같은 작업을 수행 할 수 있는 범용 함수는 없습니다 . 대신 보다 맞춤화된 접근 방식으로 문제에 대한 솔루션을 구축할 수 있는 "브릭"을 제공합니다. 이러한 "벽돌"은 grep, awk, sed등과 같은 도구입니다 .

이러한 도구 중 하나를 awk다음과 같이 사용할 수 있습니다.

vlookup.awk

FNR==NR{
  a[$1]=$2
  next
}
{ if ($1 in a) {print $1, a[$1]} else {print $1, "NA"}  }

$ awk -f vlookup.awk file2 file1
1GR_P1:001PI 1GR_P1:001PI
:040VG_L1 NA
:001PO_L3 NA
1JPI_P1:001PO_L1 1JPI_P1:001PO_L1
1JPI_P1:001PO_L2 1JPI_P1:001PO_L2

다음 column명령을 사용하여 출력을 정리할 수 있습니다.

$ awk -f vlookup.awk file2 file1 | column -t
1GR_P1:001PI      1GR_P1:001PI
:040VG_L1         NA
:001PO_L3         NA
1JPI_P1:001PO_L1  1JPI_P1:001PO_L1
1JPI_P1:001PO_L2  1JPI_P1:001PO_L2

세부 사항

awk스크립트는 값을 키로 사용하여 인덱스된 배열에 file2의 모든 내용을 넣습니다.

a[$1]=$1

file2배열을 읽은 a후 한 file1번에 한 행씩 살펴보고 결정을 내립니다. file1열 1의 값이 배열에 있는 경우 a열 2의 해당 값이 file2열 1과 함께 인쇄됩니다. file1존재하지 않으면 "NA" 메시지가 인쇄됩니다.

답변2

POSIX 명령은 다음과 join(1)매우 유사한 작업을 수행합니다 .VLOOKUP()입력 파일은 조인할 열에 이미 정렬되어 있어야 합니다..

$ sort file1 > sfile1
$ sort file2 > sfile2
$ join -a1 sfile1 sfile2
1GR_P1:001PI 1402UC
1JPI_P1:001PO_L1 1401UC
1JPI_P1:001PO_L2 1401UC
:001PO_L3
:040VG_L1

불행히도 귀하의 예에는 하나의 열만 포함되어 있으므로 join이것이 어떻게 작동하는지 실제로 설명하지 않습니다 .file1

원하는 출력을 정확하게 얻으려면 awk다른 사람들이 제안한 것처럼 연관 배열을 사용하여 간단한 스크립트를 작성할 수 있습니다.

답변3

제공한 특정 데이터 예제의 경우 다음이 작동합니다. File2필드 1로 인덱싱된 배열 에 필드 2를 로드합니다 . File1그런 다음 루프 및 배열 일치 또는 NA인쇄

awk 'NR == FNR{a[$1] = $2;next}; {print $1, $1 in a?a[$1]: "NA"}' File2 File1

답변4

awk와 redis(매우 빠른 오픈 소스 NoSQL 키-값 저장소)를 혼합해 보세요.http://redis.io더 알아보기).

awk를 사용하여 2개의 파일을 구문 분석하여 redis 명령을 생성합니다.

2개의 awk 스크립트 결과를 bash로 파이프하여 실행합니다. 그게 다야 :-)

단계별:

다음과 같이 "File2"를 구문 분석하여 redis "SET" 문을 생성합니다.

awk '{print "redis-cli SET KEY:" $1 " \"" $2"\""}' File2
redis-cli SET KEY:1JPI_P1:001PO_L1 "1401UC"
redis-cli SET KEY:1JPI_P1:001PO_L2 "1401UC"
redis-cli SET KEY:1HIK_P2:001ER "1402UC"
redis-cli SET KEY:1GR_P1:001PI "1402UC"

생성된 redis "SET" 문을 bash로 파이프하여 실행합니다.

awk '{print "redis-cli SET KEY:" $1 " \"" $2"\""}' File2 |\
 bash
OK
OK
OK
OK

다음과 같이 "File1"을 구문 분석하여 redis "GET" 문을 생성합니다.

awk '{print "printf \"" $1 " \" && redis-cli GET KEY:" $1}' File1
printf "1GR_P1:001PI " && redis-cli GET KEY:1GR_P1:001PI
printf ":040VG_L1 " && redis-cli GET KEY::040VG_L1
printf ":001PO_L3 " && redis-cli GET KEY::001PO_L3
printf "1JPI_P1:001PO_L1 " && redis-cli GET KEY:1JPI_P1:001PO_L1
printf "1JPI_P1:001PO_L2 " && redis-cli GET KEY:1JPI_P1:001PO_L2

이제 위에서 생성된 redis "GET" 문을 bash로 파이프하여 redis를 쿼리합니다.

awk '{print "printf \"" $1 " \" && redis-cli GET KEY:" $1}' File1 |\
 bash
1GR_P1:001PI "1402UC"
:040VG_L1 (nil)
:001PO_L3 (nil)
1JPI_P1:001PO_L1 "1401UC"
1JPI_P1:001PO_L2 "1401UC"

redis 가져오기 오류를 방지하려면 단일 백슬래시를 사용하여 문자열에서 큰따옴표를 이스케이프해야 합니다(slm의 답변 참조).포함된 큰따옴표를 작은따옴표로 바꾸도록 이 Perl 솔루션을 수정하려면 어떻게 해야 합니까?). 값에 큰따옴표가 많이 포함된 경우 Redis로 가져오기 위해 값을 작은따옴표로 묶을 수도 있습니다.

화타이

버니

관련 정보