특정 열에 문자열의 특정 부분만 유지

특정 열에 문자열의 특정 부분만 유지

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

id  target_id                               length  eff_length
1   intron_FBgn0000721:20_FBgn0000721:18    1136    243.944268
1   intron_FBgn0000721:19_FBgn0000721:18    1122    240.237419
2   intron_FBgn0264373:2_FBgn0264373:3      56      0
3   intron_FBgn0027570:4_FBgn0027570:3      54      0

두 번째 열의 경우 와 첫 번째 열 사이에 문자열(항상 그런 것은 아니며 때로는 다른 이름) target_id만 유지하고 싶습니다 . 따라서 새 출력 파일은 열 2에 대해 더 간단한 값을 가지지만 파일의 나머지 부분은 동일하게 유지됩니다.FBgnXXXXintron_:

sed 명령으로 시도했지만 필요하지 않은 부분을 삭제하는 방법을 모르겠습니다.

답변1

sed및 사용 column:

$ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/' file | column -t
id  target_id    length  eff_length
1   FBgn0000721  1136    243.944268
1   FBgn0000721  1122    240.237419
2   FBgn0264373  56      0

이것의 핵심 부분은 대체 명령입니다.

s/ intron_([^:]*):\S*/ \1/

intron_첫 번째 콜론 뒤와 앞의 모든 내용을 찾아 intron_변수에 저장합니다 1. [^[:space:]]*해당 콜론부터 필드 끝까지 모든 항목과 일치합니다. 그 모든 것은 변수에 저장된 텍스트로 대체됩니다 1.

awk탭으로 구분된 출력과 함께 사용 :

$ awk -v "OFS=\t" '{$2=$2;sub(/intron_/, "", $2); sub(/:.*/, "", $2); print}' file
id      target_id       length  eff_length
1       FBgn0000721     1136    243.944268
1       FBgn0000721     1122    240.237419
2       FBgn0264373     56      0

설명:

  • -v "OFS=\t"

    그러면 출력 필드 구분 기호가 탭으로 설정됩니다. 이렇게 하면 열을 정렬하는 데 도움이 되므로 column불필요해질 수 있습니다.

  • $2=$2

    라인을 인쇄할 때 awk라인에서 무언가를 변경하지 않는 한 새로 지정된 출력 필드 구분 기호로 변경되지 않습니다. 두 번째 필드를 두 번째 필드에 할당하면 출력에 탭이 있음을 보장하기에 충분합니다.

  • sub(/intron_/, "", $2)

    intron_두 번째 필드에서 제거됩니다 .

  • sub(/:.*/, "", $2)

    이렇게 하면 두 번째 필드에서 첫 번째 콜론 뒤의 모든 항목이 제거됩니다.

  • print

    그러면 새 줄이 인쇄됩니다.

awk사용자 정의 열 형식과 함께 사용

이는 위와 비슷하지만 printf원하는 대로 열 너비와 정렬 형식을 사용자 정의할 수 있도록 사용됩니다.

$ awk  '{sub(/intron_/, "", $2); sub(/:.*/, "", $2); printf "%-3s %-12s %8s %3s\n",$1,$2,$3,$4}' file
id  target_id      length eff_length
1   FBgn0000721      1136 243.944268
1   FBgn0000721      1122 240.237419
2   FBgn0264373        56   0

여기서 명령문은 printf "%-3s %-12s %8s %3s\n",$1,$2,$3,$4일반적인 printf스타일로 열 너비와 정렬을 선택합니다.

sed탭 구분에서 쉼표 구분으로 사용 및 변환

$ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/; s/[[:space:]][[:space:]]*/,/g' file 
id,target_id,length,eff_length
1,FBgn0000721,1136,243.944268
1,FBgn0000721,1122,240.237419
2,FBgn0264373,56,0

답변2

당신이 사용할 수있는 perl:

$ perl -anle '
    BEGIN {$" = "\t"}
    print "@{[@F]}" and next if $. == 1;
    $F[1] = $1 if /_([^:]*):/;
    print "@{[@F]}";
' file
id  target_id   length  eff_length
1   FBgn0000721 1136    243.944268
1   FBgn0000721 1122    240.237419
2   FBgn0264373 56      0
3   FBgn0027570 54      0

설명

  • -a: 각 줄을 배열로 자동 분할합니다 @F.

  • BEGIN {$" = "\t"}: 목록 구분 기호를 tab 으로 설정합니다. \t이는 배열이나 배열 슬라이스가 큰따옴표로 묶인 문자열에 삽입될 때 사용됩니다.

  • print "@{[@F]}" and next if $. == 1: 헤더를 인쇄하고 다음 라인으로 처리합니다.

  • $F[1] = $1 if /_([^:]*):/_: 와 first 사이의 값을 가져와서 :의 두 번째 요소에 저장합니다 @F.

  • print "@{[@F]}": 원하는 출력을 인쇄하면 됩니다.

답변3

sed -e 'h;s/.*intron_[^:]*\(:[^[:space:]]*\).*/\1/;s/./ /g;;G;;s/\(.*\)\n\(.*\)intron_\([^:]*\):[^[:space:]]*/\2\3\1/' YourFile

1 sed(파이프 없음)로 열을 유지합니다. 그것은 보유 버퍼를 사용합니다

Posix 버전( --posixGNU sed에서도 마찬가지)

관련 정보