csvkit

csvkit

다음과 같이 탭으로 구분된 파일이 있다고 가정해 보겠습니다 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

또는 이미 알고 있는 언어를 사용하여 표 형식 데이터를 쿼리할 수도 있습니다.;

구문은 간단합니다. 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 mmap.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"(작성자)를 추가하세요.

관련 정보