첫 번째와 두 번째 열을 구분 기호로 병합합니다.

첫 번째와 두 번째 열을 구분 기호로 병합합니다.

61000개의 열과 173개의 행이 있는 텍스트 파일이 있습니다. 2개 열마다 데이터를 병합하고 싶습니다. 즉, 1열과 2열을 병합하고, 3열과 4열을 병합하고, 5열과 6열을 병합해야 합니다.

입력 예(탭으로 구분):

Ind Pop scaffold1   X   scaffold1   X.1 scaffold3   X.2 scaffold4   X.3
a   antartica   1   1   1   1   2   2   1   1
b   antartica   1   1   1   1   2   1   1   2
c   antartica   1   1   1   1   2   1   1   1
d   antartica   1   1   1   1   2   1   1   2
e   antartica   1   1   1   1   2   1   1   2
f   arctic  1   1   1   1   2   1   1   1
g   arctic  1   1   1   2   2   1   1   1
h   arctic  1   1   1   1   2   1   1   1
I   arctic  1   1   1   1   2   1   1   1
j   arctic  1   1   1   1   2   1   1   1

원하는 출력(탭으로 구분):

Ind-Pop scaffold1-X scaffold2-X.1   scaffold3-X.2   scaffold4-X.3
a-antartica 1-1 1-1 2-2 1-1
b-antartica 1-1 1-1 2-1 1-2
c-antartica 1-1 1-1 2-1 1-1
d-antartica 1-1 1-1 2-1 1-2
e-antartica 1-1 1-1 2-1 1-2
f-arctic    1-1 1-1 2-1 1-1
g-arctic    1-1 1-2 2-1 1-1
h-arctic    1-1 1-1 2-1 1-1
I-arctic    1-1 1-1 2-1 1-1
j-arctic    1-1 1-1 2-1 1-1

R에서 tidyr 패키지의 unity 함수를 사용하여 이 작업을 수행해 보았습니다. 다음 명령을 사용하여 한 번에 두 개의 열을 병합할 수 있습니다.

     unite(df, newcol, c(scaffold1, X), remove=TRUE)

여러 열을 사용하여 이 작업을 수행하는 방법을 잘 모르겠습니다.

R, Perl 또는 Linux 명령줄 방법을 사용하면 매우 감사하겠습니다!

답변1

sed -E 's/([^\t]+)\t([^\t]+)/\1-\2/g'

설명하다

  • sed -E 's/foo/bar/g': 확장 정규식을 sed사용하여 실행하고 각 줄을 , 여러 번 바꿉니다.-Efoobar/g
  • ([^\t]+)\t([^\t]+)[^\t]: 탭이 아닌 문자 길이의 하나 이상의 문자를 일치시키고 +이를 그룹으로 캡처합니다 ([^\t]+). 그 뒤에는 탭 문자가 오고 다른 캡처 그룹의 탭이 아닌 문자가 옵니다.
  • \1-\2-: 첫 번째 캡처링 그룹으로 바꾼 다음 두 번째 캡처링 그룹으로 바꿉니다 . 기본적으로 탭을 -.

이것이 작동하는 이유

sed"탐욕적"입니다. 즉, 가능한 한 많은 문자를 얻으려고 합니다. 따라서 두 캡처 그룹 모두 가능한 한 오랫동안 유지하려고 노력합니다. 예를 들어, 모두 가져옵니다 a antartica( 로 대체 a-antartica). 다음에 검색을 실행하면 지나가고 antartica해당 단어 다음 탭에서 다시 검색이 시작됩니다. 그래서 다음 게임은 이고 1 1, 로 대체될 것입니다 1-1. 그러면 각 열 쌍에 대해 패턴이 반복됩니다. 탐욕 +은 중요합니다. 생략하면 각 탭만 수정되는 모드입니다.

답변2

다음은 "file.tsv" 입력에 사용할 수 있는 몇 가지 방법입니다.

$ perl -pe 's/\t/("-",$&)[$|--]/ge'  file.tsv

여기서는 모든 홀수 탭을 대시로 바꿉니다.

$ sed -e '
    y/\t/\n/
    :a;s/\n/-/;s//\t/;ta
' file.tsv

이 sed 코드는 먼저 모든 탭을 줄 바꿈으로 변경한 다음 점차적으로 홀수를 대시로, 짝수를 탭으로 변경합니다.

$ perl -lpe 's/\t(.*?(?:\t|$))/-$1/g' file.tsv

$ perl -F'\t' -lane '
      push @A, join "-", splice @F,0,2 while @F;
      print join "\t", splice @A;
' file.tsv

$ perl -F'\t' -nae '($,,$")=("\t", "-");
   print map { "@F[2*$_,2*$_+1]" } 0..$#F/2;
' file.tsv

관련 정보