다음 파일이 있습니다.
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