데이터 파일이 있습니다 A.tsv
(필드 구분 기호 = \t
).
id clade mutation
243 40A S:ojo,L:juju,S:lili
254
267 40B J:jijy,S:asel,M:ase
다음과 같이 다른 열(새 파일 B.tsv
)에 로 시작하는 돌연변이만 인쇄하고 싶습니다 .S:
id clade mutation S_mutation
243 40A S:ojo,L:juju,S:lili S:ojo,S:lili
254
267 40B J:jijy,S:asel,M:ase S:asel
awk로 몇 가지 명령을 시도했지만 결과가 없습니다.
awk -F '\t' 'BEGIN { OFS = FS } NR==1 {$(NF+1)="S_Mutation"} ; NR != 1 { $4 = ($3==^[Ss] ? $4 ) }; 1' A.tsv > B.tsv
무엇을 해야할지 아시나요? 감사해요
답변1
이를 통해 POSIX awk
그림과 같이 작동할 수 있습니다. 쉼표가 있는 세 번째 필드를 1보다 큰 행으로 분할하고 S:로 시작하는 요소를 선택한 다음 쉼표로 연결하여 마지막 +1 필드로 만듭니다.
awk -F '\t' '
BEGIN {
OFS = FS
_SEP_ = ","
}
NR==1{$(NF+1) = "S_mutation"}
NR>1&&length($3)>0{
nf = split($3, a, _SEP_)
t = ""
for (i=1; i<=nf; i++) {
if (a[i] ~ /^S:/) {
t = t (t=="" ? t : _SEP_) a[i]
}
}
$(NF+1) = t
}1
' file
똑같지만 Perl
정규식을 사용하면
perl -lnse '$,="\t";
print $_,($.==1?q(S_mutation):
"@{[/(?:\t|,)\KS:[^,]*/g]}"||());
' -- -\"=, ./file
산출:
id clade mutation S-mutation
243 40A S:ojo,L:juju,S:lili S:ojo,S:lili
254
267 40B J:jijy,S:asel,M:ase S:asel
답변2
(POSIX)를 사용하세요 awk
.
awk -F "\t" '
BEGIN { OFS = FS }
NR == 1 { $4 = "S_Mutation" }
NR > 1 && NF == 3 {
printf "%s", $0 "\t"
$0 = $3
gsub(/[^S]:[^,]*,?/, "")
sub(/,$/, "")
print $1
next
}
1' data.txt
- 행 > 1이고 필드 수 = 3인 경우
- 줄 바꿈 없이 줄을 인쇄합니다.
- 행 설정 = 필드 3
- 다음 문자로 시작하지 않는 문자열을 제거합니다.
S:
- 모든 후행 쉼표를 제거하세요.
- 줄 바꿈이 있는 필드 인쇄
- 다음 줄 처리
- 기타
- 인쇄 라인
$1
후행 탭을 인쇄하고 교체 후에 아무 것도 없는지 테스트한 다음 TAB
+ 필드를 인쇄하고 싶지 않을 것입니다 . (필드가 없는 행에 후행 탭을 원하지 않는 경우 S:xxx
. 예:
# Print line
printf "%s", $0
# Set line = field 3
$0 = $3
# Replace all N:xxx where N is not S
gsub(/[^S]:[^,]*,?/, "")
# Remove trailing comma
sub(/,$/, "")
# Print the field
if ($1 != "")
print "\t"$1
else
print ""
# Continue with next line
next
답변3
펄 사용하기
perl -F'\t' -lpe '
push @F, $. == 1 ? "S_mutation" : join ",", grep { /^S:/ } split /,/, $F[2];
$_ = join "\t", @F
' A.tsv > B.tsv
전임자.
$ perl -F'\t' -lpe '
push @F, $. == 1 ? "S_mutation" : join ",", grep { /^S:/ } split /,/, $F[2];
$_ = join "\t", @F
' A.tsv | column -t
id clade mutation S_mutation
243 40A S:ojo,L:juju,S:lili S:ojo,S:lili
254
267 40B J:jijy,S:asel,M:ase S:asel
답변4
사용해도 괜찮다면 다음을 사용하세요 sed
.
sed 'h;s/.*[[:space:]]/,/;s/,[^S]:[^,]*//g;x;G;s/\n,/\t/'
\t
GNU에서만 작동 합니다 sed
. 다른 스타일의 경우 ctrlv일반적으로 텍스트 탭은 입력한 다음 Tab 키를 눌러 삽입됩니다.
개념은 행을 예약된 공간에 유지한 다음 마지막 열을 격리하고 변형을 제외한 모든 것을 제거하는 것입니다 S:
. 그런 다음 저장된 행의 마지막 열로 추가합니다.
h
해당 줄을 예약된 공간에 복사하세요.s/.*[[:space:]]/,/
마지막 탭이나 공백 앞의 모든 내용을 쉼표로 바꾸십시오. 따라서 마지막 열을 유지하고 앞에 쉼표를 추가하십시오. 이 쉼표는 다음 단계에서 도움이 될 것입니다s/,[^S]:[^,]*//g
S:
제외한 모든 요소를 제거합니다.x
보관 공간과 패턴 공간을 교환하여G
보관 공간에 유지된 원래 열에 새 열이 추가되도록 합니다.s/\n,/\t/
마지막으로 탭을 통해 도입한 추가 개행 문자와 쉼표를 대체합니다.