다음과 같은 파일이 있습니다.
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
사용 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 /_([^:]*):/
_
: 첫 번째와 사이의 값을 가져:
와서 의 두 번째 요소에 저장합니다@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)