두 번째 파일 키를 기반으로 첫 번째 열을 사용하여 첫 번째 파일을 정렬하는 솔루션을 찾으려고 합니다.
첫 번째 파일 예(file1.csv)
COLUMN1 COlUMN2
apple fruit
dog animal
cat animal
cow animal
두 번째 파일 예시(sort_keys.txt)
cat
dog
apple
cow
예상 출력(sorted.txt)
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
지금까지 도움이 될 수 있는 sort 명령과 awk 명령을 찾았지만 작동하는 코드가 없습니다.
$> awk 'NR==FNR{o[FNR]=$1; next} {t[$1]=$0} END{for(x=1; x<=FNR; x++){y=o[x]; print t[y]}}' sort_key.txt file1.csv
그러나 명령이 예상대로 작동하지 않으며 이에 대해서는 전문가의 조언이 필요합니다. PS 저는 Linux 명령에 대한 지식을 가지고 있지만 이는 매우 구체적이어서 구현 방법을 모르겠습니다.
어떤 도움이나 조언이라도 대단히 감사하겠습니다.
답변1
$ awk 'NR==1; NR==FNR{a[$1]=$2; next} {print $1, a[$1]}' file1 sort_keys.txt
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
답변2
GNU awk(별명)가 있으면 gawk
사용자 정의 정렬 기능을 정의하고 사용할 수 있습니다.
예를 들어 PROCINFO
GNU awk > 4.0의 배열 반복 함수를 가정하면 다음과 같습니다.
$ gawk '
function mysort(ia,va,ib,vb){return o[ia] - o[ib]}
NR==FNR{o[$1]=FNR; next} # map keys to numerical order
FNR==1{print; next} # print + skip the header line
{a[$1]=$0}
END{
PROCINFO["sorted_in"] = "mysort"
for(i in a) print a[i]
}
' sort_key.txt file1.csv
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
(이전 GNU awks에서는 asorti
.
답변3
데이터가 그다지 크지 않은 경우 2차 복잡도를 갖는 간단한 솔루션은 다음과 같습니다.
cat sort_keys.txt | while read key ; do egrep "^$key " file1.csv ; done
헤더를 추가/제거하려면 head
필요에 따라 및 명령을 추가하세요.tail
답변4
당신은 그것을 사용할 수 있습니다 join
. 에서 man join
:
동일한 조인 필드가 있는 각 입력 행 쌍에 대해 표준 출력에 한 행을 씁니다. 기본 조인 필드가 먼저 공백으로 구분됩니다.
첫 번째 행은 정렬되어서는 안 됩니다.
총 길이 DR:
head -n 1 file1.csv; join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort) | sort -n -k 2 | awk '{ print $1, $3 }'
일을 할 것입니다.
설명하다
기본적으로 우리는:
- file1.csv의 첫 번째 줄을 추출합니다.
- 첫 번째 필드에서 sort_keys를 사용하여 file1.csv의 나머지 부분을 연결합니다.
- sort_keys 순서로 결과 정렬
또한 join
파일을 정렬해야 합니다.
이는 우리를 다음으로 이끌 것입니다:
- 첫 번째 입력으로 sort_keys 파일(이전 필드에서)에 번호를 매기고(마지막에 이 원래 순서를 사용할 수 있도록) 두 번째 필드를 정렬합니다.
cat -n sort_keys.txt | sort -k 2
3 apple
1 cat
4 cow
2 dog
- 두 번째 입력으로 csv 파일을 가져와 첫 번째 행을 건너뛰고 첫 번째 필드에서 정렬합니다.
tail -n +2 file1.csv | sort
apple fruit
cat animal
cow animal
dog animal
- 그런 다음 첫 번째 프로세스의 두 번째 필드( )를 사용하여
-1 2
이들을 결합 할 수 있습니다.
join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort)
apple 3 fruit
cat 1 animal
cow 4 animal
dog 2 animal
- 이제 조인 결과를 두 번째 필드에서 숫자로 정렬할 수 있으며(sort_keys가 9개 항목을 초과하는 경우) 첫 번째와 세 번째 필드만 유지합니다.
``... |sort -n -k 2 '{ $1, $3 인쇄 }'
cat animal
dog animal
apple fruit
cow animal
- 마지막으로 이것을 file1.csv의 첫 번째 줄 앞에 추가합니다.
head -n 1 file1.csv; join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort) | sort -n -k 2 | awk '{ print $1, $3 }'
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
더 나아가
실제 데이터에 따라 필드 번호와 필드 구분 기호를 조정해야 합니다.
키가 sort_keys에 없는 데이터 행이나 sort_keys에 해당 데이터 행이 없는 행을 유지하려고 할 수도 있습니다( -a
조인 옵션 참조).
자유롭게 사용해 보세요 join
!