행에서 중복된 값을 제거하는 방법은 무엇입니까?

행에서 중복된 값을 제거하는 방법은 무엇입니까?

다음과 같은 파일이 있습니다.

$ cat file
    rep1 rep2
g1001_INpfu_DN44908_c3_g1 17.85 19.95
g10042/1330/2846_INpfu_DN43979_c0_g3 34.07 29.19
g1077/1457/278/278_INpfu_PRJNA287145_DN42983_c0_g1 20.69 21.64
g100/100_INpfu_DN43143_c0_g1 52.36 33.64
g79/79/79/79_INpfu_DN45068_c4_g1 58.83 74.58

첫 번째 "_" 앞의 텍스트는 그룹 번호입니다. 예를 들어

  • G숫자_ ...
  • G번호 1/2_ ...
  • G번호 1/2/3_ ...

(설명의 편의를 위해 공백을 넣었습니다.) 슬래시는 여러 그룹을 의미합니다. 가끔 중복된 그룹번호가 연속으로 있어서 삭제하고 싶은 경우가 있습니다.

예상 결과는 다음과 같아야 합니다.

    rep1 rep2
g1001_INpfu_DN44908_c3_g1 17.85 19.95
g10042/1330/2846_INpfu_DN43979_c0_g3 34.07 29.19
g1077/1457/278_INpfu_PRJNA287145_DN42983_c0_g1 20.69 21.64
g100_INpfu_DN43143_c0_g1 52.36 33.64
g79_INpfu_DN45068_c4_g1 58.83 74.58

마지막 세 행에서는 동일한 그룹 번호가 제거되고 고유한 그룹 번호만 남습니다.

답변1

다음을 사용하여 이와 같은 것을 시도해 볼 수 있습니다 sed.

$ sed -e :a -e 's:\([0-9][0-9]*\)/\1:\1:' -e ta file
rep1 rep2
g1001_INpfu_DN44908_c3_g1 17.85 19.95
g10042/1330/2846_INpfu_DN43979_c0_g3 34.07 29.19
g1077/1457/278_INpfu_PRJNA287145_DN42983_c0_g1 20.69 21.64
g100_INpfu_DN43143_c0_g1 52.36 33.64
g79_INpfu_DN45068_c4_g1 58.83 74.58

부분 일치를 처리하려면(예: and 로 변환하지 않음 g512/12/x) 양쪽 에 숫자가 아닌 앵커를 추가할 수 있습니다.g512/5120/xg512/xg5120/x

sed -e :a -e 's:\([^0-9]\)\([0-9][0-9]*\)/\2\([^0-9]\):\1\2\3:' -e ta file

또는 좀 더 읽기 쉽게 확장 정규식을 사용하세요.

sed -E -e :a -e 's:([^0-9])([0-9]+)/\2([^0-9]):\1\2\3:' -e ta file

전임자. 주어진

$ cat file
    rep1 rep2
g1001_INpfu_DN44908_c3_g1 17.85 19.95
g10042/1330/2846_INpfu_DN43979_c0_g3 34.07 29.19
g1077/1457/278/278_INpfu_PRJNA287145_DN42983_c0_g1 20.69 21.64
g512/12_INpfu_DN43143_c0_g1 52.36 33.64
g100/100_INpfu_DN43143_c0_g1 52.36 33.64
g512/5120_INpfu_DN43143_c0_g1 52.36 33.64
g79/79/79/79_INpfu_DN45068_c4_g1 58.83 74.58

그 다음에

$ sed -E -e :a -e 's:([^0-9])([0-9]+)/\2([^0-9]):\1\2\3:' -e ta file
    rep1 rep2
g1001_INpfu_DN44908_c3_g1 17.85 19.95
g10042/1330/2846_INpfu_DN43979_c0_g3 34.07 29.19
g1077/1457/278_INpfu_PRJNA287145_DN42983_c0_g1 20.69 21.64
g512/12_INpfu_DN43143_c0_g1 52.36 33.64
g100_INpfu_DN43143_c0_g1 52.36 33.64
g512/5120_INpfu_DN43143_c0_g1 52.36 33.64
g79_INpfu_DN45068_c4_g1 58.83 74.58

답변2

그리고 perl:

perl -pe 's{^g(?:\d+/)*?(\d+)\K(?:/\1)+(?!\d)}{}' < your-file

g/number/number[/number...]/number이는 선두 부분에서 처음으로 반복되는 숫자 시퀀스만 제거하고 해당 부분 뒤에 숫자가 없는 경우에만 제거한다는 점에서 엄격합니다 .

다음을 사용하여 sed동일한 작업을 수행할 수 있습니다 .

sed '
  \|^\(g\([[:digit:]]\{1,\}/\)*[[:digit:]]\{1,\}\).*| {
    h; # save a copy of original line
    s||\1:|; # remove all but the leading g/x/y/z
    s|\([g/]\)\([[:digit:]]\{1,\}\)\(/\2\)\{1,\}\([^[:digit:]]\)|\1\2\4|
    G; # append saved copy
    s|:\ng\([[:digit:]]\{1,\}/\)*[[:digit:]]\{1,\}||; # remove excess
  }' < your-file

관련 정보