파일 A의 내용을 변경하지 않고 파일 A의 열 3을 기준으로 파일 B를 정렬합니다.

파일 A의 내용을 변경하지 않고 파일 A의 열 3을 기준으로 파일 B를 정렬합니다.

다음 파일이 있습니다.

cat fileA.txt

seattle    1991  west
atlanta    1993  west
turlock    1998  west
marysville 2004  south
newyork    2007  north
canada     2004  west

두 번째 파일은 다음과 같습니다.

cat fileB.txt

popular
someWhatPopular
boring
popular
popular
popular

다음 출력을 얻고 싶습니다 fileB.txt.

popular popular popular someWhatPopular boring popular

그래서 본질적으로 저는 세 번째 열로 fileB.txt정렬 하고 싶습니다fileA.txt

다음 코드를 시도했습니다.

   #!/bin/bash
   sort -s -k3,3 fileA.txt fileB.txt

그러나 그것은 작동하지 않았습니다. 어떤 제안이 있으십니까? 나는 하드코딩이 필요하지 않은 모든 것에 열려 있습니다. 배쉬/awk/sed 등

답변1

이는 Linux보다 더 중요한 데이터 구조 문제입니다. "데이터베이스"에서와 마찬가지로 두 테이블을 연결하려면 두 테이블에 공통 항목(키)이 필요하며 데이터 테이블의 첫 번째 열에 고유 키를 유지하는 것이 좋습니다. 그런 다음 마음에 드는 내용을 정렬하고 연결할 수 있습니다.

@glennjackman의 지도와 같은 것을 사용하여 지도 키를 북쪽, 남쪽 등으로 정의할 수 있습니다.

1 south somewhatPopular
2 west popular
3 north boring
4 east unexplored

file이라는 파일에 popularity. fileA고유 키를 포함하도록 수정

1 seattle    1991  west
2 atlanta    1993  west
3 turlock    1998  west
4 marysville 2004  south
5 newyork    2007  north
6 canada     2004  west

join그런 다음 선택한 키(귀하의 경우 열 2가 popularity열 4에 매핑됨 fileA) 를 조작하여 이러한 파일을 조작 할 수 있지만 join 두 파일 모두 키 필드에서 정렬해야 하므로

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity) | sort -k2 | awk '{print $6}'

popular
popular
popular
somewhatPopular
boring
popular

약간의 큰 망치 접근 방식이지만 최대의 유연성을 제공합니다.

각 파이프라인에서 위 명령을 분석하면 각 단계의 기능을 확인할 수 있습니다.

편집 : 설명join -1 4 -2 2 # its in the man pages

이는 join표 1의 네 번째 열(-1 4)을 보고 표 2의 두 번째 열(-2 2)에서 일치하는 값을 찾으라는 의미입니다.

join그런 다음 두 테이블의 열을 단일 테이블로 결합하되 키 열은 한 번만 포함합니다(북쪽 등). 출력 보기

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity)

더 명확해야

join이것이 작동 하려면 데이터 테이블을 정렬해야 하기 때문에

| sort -k2

테이블을 결합하면 원래 순서로 돌아갑니다.

원하는 열은 결합된 테이블의 열 6이므로

| awk '{print $6}'

표준 출력으로.

답변2

paste두 개의 "테이블" 파일을 함께 모아서 출력을 파이프로 연결한 sort다음 cut네 번째 열만 유지할 수 있습니다 .

테스트되지 않은(현재는 모바일) 시도는 다음과 같습니다.

paste fileA fileB | sort -s -k3,3 | cut -f4

답변3

다음을 사용하여 알파벳 매핑을 얻을 수 있습니다.

paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)
north   boring
south   popular
west    someWhatPopular

그런 다음 awk를 사용하여 다음 형식으로 원하는 출력을 생성할 수 있습니다.

awk '
    NR==FNR {map[$1] = $2; next} 
    {print map[$NF]}
' <(paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)) fileA.txt
someWhatPopular
someWhatPopular
someWhatPopular
popular
boring
someWhatPopular

관련 정보