중복된 이름을 제거하고 고유한 이름 뒤에 배열을 인쇄하는 방법

중복된 이름을 제거하고 고유한 이름 뒤에 배열을 인쇄하는 방법

아래 예와 같이 동일한 이름을 가진 KO 카테고리를 축소하고 각 카테고리에 할당된 유전자 이름을 배열로 인쇄하는 방법입니다.

나는 이것을 가지고있다:

K00002  gene_65472
K00002  gene_212051
K00002  gene_403626
K00003  gene_666
K00003  gene_5168
K00003  gene_7635
K00003  gene_12687
K00003  gene_175295
K00003  gene_647659
K00003  gene_663019
K00004  gene_88381
K00005  gene_30485
K00005  gene_193699
K00005  gene_256294
K00005  gene_307497

그리고 이것을 원합니다:

K00002  gene_65472  gene_212051 gene_403626             
K00003  gene_666    gene_5168   gene_7635   gene_12687  gene_175295 gene_647659 gene_663019
K00004  gene_88381                      
K00005  gene_30485  gene_193699 gene_256294 gene_307497 

다음 명령이 작동했습니다(다음 명령에서 가져옴).로아이마의 대답):

tr -d '\r' < file| awk '$1 != p { if (p>"") {printf "\n"} printf "%s",$1; p=$1 } { printf "\t%s",$2 } END { if(p>"") {printf "\n"} }' > output

답변1

더 많은 것

awk '$1 != p { if (p>"") {printf "\n"} printf "%s",$1; p=$1 } { printf "\t%s",$2 } END { if(p>"") {printf "\n"} }' datafile

K00002  gene_65472      gene_212051     gene_403626
K00003  gene_666        gene_5168       gene_7635       gene_12687      gene_175295     gene_647659     gene_663019
K00004  gene_88381
K00005  gene_30485      gene_193699     gene_256294     gene_307497

이별을 원하지 않는다면\t그런 다음 공백으로 변경하십시오 .

작동 방식은 다음과 같습니다.

# Each line is processed in turn. "p" is the previous line's key field value

# Key field isn't the same as before
$1 != p {
    # Flush this line if we have printed something already
    if (p > "") { printf "\n" }

    # Print the key field name and set it as the current key field
    printf "%s", $1; p = $1
}

# Every line, print the second value on the line
{ printf "\t%s", $2 }

# No more input. Flush the line if we have already printed something
END {
    if (p > "") { printf "\n" }
}

로부터희미한 코멘트당신은만들기모든 사람의 답변에 대해 근본적인 문제는 Windows 시스템에서 생성된 데이터 파일을 사용하고 있으며 UNIX/Linux 플랫폼에서 작동할 것으로 예상한다는 것입니다. 그러지 마세요. 또는 꼭 필요한 경우 먼저 파일을 올바른 형식으로 변환하세요.

dos2unix < datafile | awk '...'       # As above

tr -d '\r' < data file | awk '...'    # Also as above

답변2

파일:

K00002  gene_65472
K00002  gene_212051
K00002  gene_403626
K00003  gene_666
K00003  gene_5168
K00003  gene_7635
K00003  gene_12687
K00003  gene_654221
K00003  gene_663019
K00004  gene_88381
K00005  gene_30485
K00005  gene_193699
K00005  gene_256294

awk 사용:

awk '1 {if (a[$1]) {a[$1] = a[$1]" "$2} else {a[$1] = $2}} END {for (i in a) { print i,a[i]}}' file

산출:

K00002 gene_65472 gene_212051 gene_403626
K00003 gene_666 gene_5168 gene_7635 gene_12687 gene_654221 gene_663019
K00004 gene_88381
K00005 gene_30485 gene_193699 gene_256294

나는 이것을 가져갔다우편참고로.

답변3

밀러를 사용하여http://johnkerl.org/miller/doc
~와 함께

mlr --csv --implicit-csv-header --headerless-csv-output cat -n -g 1 then label a,b,c then reshape -s a,c then unsparsify --fill-with "" input.csv

이 예제는 csv 입력입니다.

A,234
A,4945
B,8798
B,8798
B,790

당신은 할 것

A,234,4945,
B,8798,8798,790

답변4

값에 공백이 없고 공백으로 구분되어 있다고 가정합니다. 또한 데이터가 이름이 지정된 파일에 있다고 가정합니다 file(탭으로 구분된 버전은 아래 참조).

for x in $(<file cut -d ' ' -f 1 | sort | uniq); do
    printf '%s %s\n' "$x" "$(grep "$x" file | cut -d ' ' -f 2- | tr '\n' ' ' | sed 's/.$//')"
done

이는 다음을 수행합니다.

  • 첫 번째 필드의 고유 값을 추출합니다.
    • cut-f 1줄의 첫 번째 덩어리( )만 선택하고 각 공백( -d ' ')에서 분리합니다.
    • sort | uniq첫 번째 필드의 값을 정렬하고 각 필드를 한 번만 출력합니다(또는더 짧고 더 효율적: sort -u);
  • 각각:
    • file에서 관련 라인을 모두 추출합니다 grep.
    • cut( -f 2-"두 번째 및 다음 필드를 가져옴"을 의미함)을 사용하여 첫 번째 필드를 제거합니다 .
    • 나머지를 공백으로 구분된 값 목록( tr)으로 변환합니다.
    • 불필요한 공백인 마지막 문자를 제거하십시오 sed(예, 이것은 정말 우아하지 않습니다).
    • 결과를 첫 번째 필드의 값에 연결하고 표준 출력으로 인쇄합니다.

입력이 탭으로 구분되어 있고 탭으로 구분된 출력을 원하는 경우 위의 코드는 다음과 같습니다.

for x in $(<file cut -f 1 | sort | uniq); do
    printf '%s\t%s\n' "$x" "$(grep "$x" file | cut -f 2- | tr '\n' '\t' | sed 's/.$//')"
done

노트:

  1. 성능: 이 접근 방식의 실행 시간은 awk기반 솔루션의 실행 시간보다 훨씬 높습니다.로아이마의 대답). 적어도 몇 배는 됩니다.
  2. 반면에 이 접근 방식은 입력 파일이 정렬되지 않은 경우에도 작동합니다.
  3. 이러한 종류의 솔루션이 작업을 효과적으로 수행하는 빠르고 (그리고 더러운?) 방법임에도 불구하고 쉘 루프를 사용하여 텍스트를 처리하는 것은 일반적으로 권장되지 않습니다. 참고로 보세요 "쉘 루프를 사용하여 텍스트를 처리하는 것이 나쁜 습관으로 간주되는 이유는 무엇입니까?".

관련 정보