두 개의 열이 있는 탭으로 구분된( ) 파일이 있습니다 \t
.
a_1 T_b
a_2 T_c
a_2 T_d
a_2 T_e
a_3 T_f
a_4 B_a
a_4 B_b
이제 이것을 한 줄에 하나의 샘플이 있는 파일로 변환하고 싶습니다. 각 샘플의 모든 값은 다음과 같이 같은 줄에 공백으로 구분된 세 번째 필드입니다.
a_1 T_b
a_2 T_c T_d T_e
a_3 T_f
a_4 B_a B_b
방금 두 번째 파일에서 첫 번째 파일로의 awk 변환을 마스터했습니다. 그러니 제게 조언을 좀 해주시고 저의 부족한 유닉스 기술을 용서해 주십시오. 감사합니다.
답변1
datamash
첫 번째 탭으로 구분된 열을 기준으로 그룹화하고 GNU를 사용하여 다른 열을 축소합니다.
$ datamash groupby 1 collapse 2 <file
a_1 T_b
a_2 T_c,T_d,T_e
a_3 T_f
a_4 B_a,B_b
이는 파일이 첫 번째 필드를 기준으로 정렬되어 있다고 가정합니다. 그렇지 않은 경우 datamash
해당 -s
( ) 옵션을 사용하거나 를 통해 --sort
데이터를 파이프하십시오 .datamash
sort
두 번째 필드의 "하위 필드"를 쉼표 대신 공백으로 구분하려면 다음 명령을 사용하여 쉼표를 공백으로 바꾸십시오 awk
.
$ datamash groupby 1 collapse 2 <file | awk -F '\t' 'BEGIN { OFS=FS } { gsub(","," ",$2) }; 1'
a_1 T_b
a_2 T_c T_d T_e
a_3 T_f
a_4 B_a B_b
답변2
한 가지 방법은 다음과 같습니다.
$ awk -F'\t' '
{
$1 in a? a[$1]=a[$1]" "$2 : a[$1]=$2
}
END{
for(i in a){print i"\t"a[i]}
}' file
a_1 T_b
a_2 T_c T_d T_e
a_3 T_f
a_4 B_a B_b
여기서의 아이디어는 a
키가 샘플 이름인 첫 번째 필드인 연관 배열을 생성한다는 것입니다. 그런 다음 각 행에 대해 해당 샘플이 이미 키로 존재하는 경우 해당 값을 행의 두 번째 필드에 설정하고, 그렇지 않은 경우 현재 두 번째 필드를 기존 값에 추가합니다. 동일한 내용을 다음과 같이 더 자세히 작성할 수 있습니다.
$ awk -F'\t' '
{
if($1 in a){ a[$1]=a[$1]" "$2 }
else { a[$1]=$2 }
}
END{
for(i in a){print i"\t"a[i]}
}' file
답변3
Raku(이전 Perl_6) 사용
raku -e 'my %hash; for lines>>.words() {%hash.append( .[0] => .[1] )}; .say for %hash.sort;'
또는
raku -e 'my %hash; for lines.map(*.words) -> ($k,$v) {%hash.append: $k => $v }; .say for %hash.sort;'
간단히 말해서, Raku에 내장된 해싱 기능이 이 문제를 해결하는 데 사용됩니다. 행을 읽고 (공백으로 구분) 으로 분할합니다 words
. 단어는 해시에 추가되며 %hash
첫 번째 열은 키가 되고 두 번째 열은 값이 됩니다. Raku의 =>
"fat arrow" 연산자는 키-값 쌍을 구성하는 데 사용되며 append
루틴은 키를 기반으로 값을 누적합니다(해시는 중복 키를 가질 수 없습니다).
입력 예:
a_1 T_b
a_2 T_c
a_2 T_d
a_2 T_e
a_3 T_f
a_4 B_a
a_4 B_b
예제 출력:
a_1 => T_b
a_2 => [T_c T_d T_e]
a_3 => T_f
a_4 => [B_a B_b]
.say
.put
탭으로 구분된 출력을 얻으 려면 위의 코드를 변경하세요 \t
. 또는 자신만의 필드 구분 기호를 정의하세요. 아래 예에서 첫 번째와 두 번째 열은 4개의 공백으로 구분되고 value
두 번째 열은 쉼표로 구분됩니다(필요한 경우 공백으로 변경).
~$ raku -e 'my %hash; for lines.map(*.words) -> ($k,$v) {%hash.append: $k => $v }; for %hash.sort {put .key, " ", .value.join(",")};'
a_1 T_b
a_2 T_c,T_d,T_e
a_3 T_f
a_4 B_a,B_b
https://docs.raku.org/언어/hashmap#Mutable_hashes_and_immutable_maps
https://docs.raku.org/routine/=%3E
https://raku.org