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

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

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

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첫 번째 열과 두 번째 열 사이의 문자열만 유지하고 싶습니다 FBgnXXXX(항상 그런 것은 아니며 때로는 다른 이름도 있음). 따라서 새 출력 파일의 열 2에 있는 값은 더 단순해지지만 파일의 나머지 부분은 동일하게 유지됩니다.intron_:

sed 명령을 사용해 보았지만 필요하지 않은 부분을 제거하는 방법을 모르겠습니다.

답변1

사용 sedcolumn:

$ 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 /_([^:]*):/_: 첫 번째와 사이의 값을 가져 :와서 의 두 번째 요소에 저장합니다 @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 버전( --posix또한 GNU sed)

관련 정보