다음과 같이 탭으로 구분된 파일이 있다고 가정해 보겠습니다 data.tsv
.
1 a 3
2 b 2
3 a 10
2 c 2
2 a 8
이제 다음 명령을 사용하여 열 1의 값을 ID에서 이름으로 변환하고 싶습니다 map.tsv
.
1 foo
2 bar
3 baz
결과는 다음과 같습니다.
foo a 3
bar b 2
baz a 10
bar c 2
bar a 8
나는 알고있다하나일부 AWK 트릭을 사용하여 매핑을 수행하는 것이 가능하지만 여러 열에 대해 여러 매핑을 사용하고 다음과 같이 간단한 호출을 할 수 있기를 바랍니다.
$ my_map_command 1:map.tsv < data.tsv
비슷한 작업을 수행하는 명령이 있습니까?
답변1
csvkit
csvjoin
패키지의 명령csvkit비슷한 동작을 달성하는 데 사용할 수 있습니다.
$ csvjoin -tH -c 1,1 data.tsv map.tsv 2> /dev/null
a,b,c,b2
1,a,3,foo
2,b,2,bar
3,a,10,baz
2,c,2,bar
2,a,8,bar
csvcut
열 재정렬/제거는 간단하며 동일한 패키지에서 수행할 수 있습니다.
핵심 도구
이 기준을 사용할 수도 join(1)
있지만 데이터를 정렬해야 합니다(정렬되지 않은 경우 지도도 포함).
$ join -j1 -t ' ' <(sort -k1 data.tsv) map.tsv
1 a 3 foo
2 a 8 bar
2 b 2 bar
2 c 2 bar
3 a 10 baz
두 경우 모두 한 번에 하나의 매핑만 수행할 수 있으므로 추가 호출을 위해 여러 매핑을 파이프로 연결해야 합니다.
답변2
다음 파일에 넣으십시오 my_map_command
.
#!/usr/bin/awk -f
FNR==NR{map[$1]=$2}
FNR!=NR{
printf "%s%s",map[$1],OFS
for (i=2; i<=NF; i++) printf "%s%s",$i,OFS
printf "\n"
}
그런 다음 다음을 실행하십시오.
chmod u+x my_map_command
다음과 같이 스크립트를 호출하십시오.
./my_map_command map.tsv data.tsv
여러 지도 파일:
./my_map_command <(cat map1.tsv map2.tsv) data.tsv
답변3
파일 매개변수 사이에 변수를 할당합니다.
awk '!data{map[$1]=$2; next} $1 in map{$1=map[$1]} 1' map1 map2... data=1 data
map
플래그가 제공될 때까지 값을 배열로 읽습니다.- 플래그 값(
data=1
매개변수)을 지정한 후 데이터의 필드를 매핑된 값으로 교환합니다.
awk '
!data {
map[field,$1]=$2
maps[field]
next
}
{
for (i in maps)
if ((i,$i) in map)
$i=map[i,$i]
}
1' field=1 map1 field=2 map2 data=1 data
data
값에 대한 맵 의 필드 1map1
data
값에 대한 맵 의 필드 2map2
답변4
또는 이미 알고 있는 언어를 사용하여 표 형식 데이터를 쿼리할 수도 있습니다.SQL;
구문은 간단합니다. q "<SQL Query>"
또는 q -t "…"
파일이 tsv이거나 -d …
다른 구분 기호인 경우입니다. 귀하의 쿼리는 다음과 같습니다:
SELECT m.c2, d.c2, d.c3
FROM data.tsv AS d INNER JOIN map.tsv AS m
ON d.c1==m.c1
q - text as data
(포장된 어디에나)는 적용할 수 있는 깔끔한 도구입니다.SQL모든 테이블 형식의 구분된 데이터입니다. STDIN도 작동합니다. 파일 이름으로 "-"를 지정하고 JOIN - as m
map.tsv를 입력한 내용으로 바꾸는 것이 좋습니다.
좋은 "보너스" q
: SQL을 사용하여 계산을 수행 할 수도 ORDER
있습니다 ! GROUP
모두 표시:
q 'SELECT m.c2 AS I, d.c2, d.c3, ROUND(d.c3*0.4, 2) as b
FROM data.tsv AS d INNER JOIN - AS m
ON d.c1==m.c1
ORDER BY I' < map.tsv
bar b 2 0.8
bar c 2 0.8
⋮
참고: "q"라는 이름은 검색할 수 없으므로 검색할 때 "text-as-data" 또는 "harelba"(작성자)를 추가하세요.