
다음과 같은 파일이 있습니다.
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에 대해 더 간단한 값을 가지지만 파일의 나머지 부분은 동일하게 유지됩니다.FBgnXXXX
intron_
:
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 버전( --posix
GNU sed에서도 마찬가지)