아래와 같이 탭으로 구분된 열 텍스트가 있습니다.
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
위의 표를 아래와 같이 변환하려면 어떻게 해야 합니까?
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
실제 데이터 파일을 추출했습니다. 탭으로 구분된 파일입니다. 귀하(Stéphane Chazelas?)가 게시한 명령줄을 시도해 보았지만 제대로 작동하지만 마지막 열의 중복 항목을 제거할 수 없습니다.
A CD274 PDCD1LG2 CD276 PDCD1LG2 CD274
B NEK2 NEK6 NEK10 NEK10 NEKL-4
C TNFAIP3 OTUD7B OTUD7B TNFAIP3 TNFAIP3
D DUSP16 DUSP4 DUSP8 VHP-1 DUSP8
E AGO2 AGO2 AGO2 AGO2 AGO2
출력은 다음과 같아야합니다
A CD274 CD276 PDCD1LG2
B NEK2 NEK6 NEK10 NEKL-4
C TNFAIP3 OTUD7B
D DUSP16 DUSP4 DUSP8 VHP-1
E AGO2
답변1
첫 번째 샘플 데이터 세트:
$ awk -vOFS='\t' '{ r=""; delete t; for (i=1;i<=NF;++i) { if (!t[$i]++) { r = r ? r OFS $i : $i } } print r }' file
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
두 번째 예제 데이터 세트(동일 awk
스크립트):
$ awk -vOFS='\t' '{ r=""; delete t; for (i=1;i<=NF;++i) { if (!t[$i]++) { r = r ? r OFS $i : $i } } print r }' file
A CD274 PDCD1LG2 CD276
B NEK2 NEK6 NEK10 NEKL-4
C TNFAIP3 OTUD7B
D DUSP16 DUSP4 DUSP8 VHP-1
E AGO2
스크립트는 입력 파일을 한 줄씩 읽고 file
각 줄에 대해 각 필드를 반복하여 출력 줄을 작성합니다 r
. 필드의 값이 출력 줄에 추가된 경우( t
사용된 필드 값의 조회 테이블에 의해 결정됨) 이면 해당 필드가 무시되고, 그렇지 않으면 추가됩니다.
입력 행의 모든 필드가 처리되면 구성된 행이 출력됩니다.
-vOFS='\t'
출력 필드 구분 기호는 명령줄에서 탭으로 설정됩니다.
공개된 스크립트 awk
:
{
r = ""
delete t
for (i = 1; i <= NF; ++i) {
if (!t[$i]++) {
r = r ? r OFS $i : $i
}
}
print r
}
답변2
sed/tr, uniq 및 붙여넣기
while read -r l; do sed 's/\t/\n/g' <<< "$l" | uniq | paste -s; done < test
또는 POSIX 호환:
while read -r l; do echo "$l" | tr '\t' '\n' | uniq | paste -s -; done < test
파일의 경우 모든 문자를 한 줄씩 개행 문자로 바꾸고, 중복 항목을 제거하고 개행 문자를 다시 문자로 바꾸기 위해 실행 test
합니다 .Tabuniq
Tab
$ cat test
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
$ while read -r l; do sed 's/\t/\n/g' <<< "$l" | uniq | paste -s; done < test
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
알아채다: 이 솔루션은아니요여러 줄에 걸친 중복 작업에 사용됩니다 C1
.
A B1 B1 C1
C1 B B2 D2
답변3
어쩌면 다음과 같은 것일 수도 있습니다.
gawk -vRS='\\s*\\S*' -vORS= '{$0=RT};$1!=prev;{prev=$1}'
RS=pattern
...트릭을 사용하면 {$0=RT}
패턴과 일치하는 부분으로 정의된 레코드를 처리할 수 있습니다.
따라서 여기서는 입력을 <whitespace><non-whitespace>
$0
레코드 로 자르고 (첫 번째이자 유일한 필드)를 <non-whitespace>
입력합니다 . 이전 기록과 동일하지 않은 기록을 $1
인쇄하고 있습니다 .$1
다음과 같이 입력하면:
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
기록은 다음과 같습니다
[A][ B1][ B1][ C1][ 비][ B2][ D2][ C][ C12][ C13][ C13][ 디][ D3][ D5][ D9][ G][ F2][ F2][ ]
그러나 두 번째 예에서는 작동하지 않습니다. 일부 개행 문자가 제거될 수 있습니다.
답변4
그리고 perl
:
각 줄에는 고유한 단어가 있습니다.
perl -MList::Util=uniq -lape '$_ = join "\t", uniq @F'
세상에서 유일한 단어:
perl -lape '$_ = join "\t", grep {!$count{$_}++} @F'
아니면 두 번째 줄부터 시작하는 각 단어 줄을 고려해 보세요 .
perl -lape '$_ = join "\t", shift(@F), grep {!$count{$_}++} @F'