편집해야 하는 입력 파일은 다음과 같습니다(더 많은 행이 있을 수 있음).
bundle_id target_id length eff_length tot_counts uniq_counts est_counts eff_counts ambig_distr_alpha ambig_distr_beta fpkm fpkm_conf_low fpkm_conf_high solvable tpm
1 intron_FBgn0035847:4_FBgn0035847:3 61 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
2 intron_FBgn0032515:2_FBgn0032515:4 72 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
3 intron_FBgn0266486:5_FBgn0266486:4 58 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
4 intron_FBgn0031359:10_FBgn0031359:7 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
4 intron_FBgn0031359:10_FBgn0031359:8 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
4 intron_FBgn0031359:10_FBgn0031359:9 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
536 intron_CR31143:1_CR31143:2 40 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
두 번째 열의 각 ID에 대해인트론_XXXXXXXX:X_XXXXXXXX:X, 사이의 문자열을 추출하고 싶습니다인트론_그리고 첫 번째:(일반적으로 문자열 사이에 있지만 항상 FBgn으로 시작하는 것은 아닙니다).
그런 다음 다음과 같은 목록이 있습니다.FBGNFBgn을 변환하려는 해당 이름의 다른 열:
## FlyBase Gene Mapping Table
## Generated: Fri Dec 20 12:37:29 2013
## Using datasource: dbi:Pg:dbname=fb_2014_01_reporting;host=flysql9;port=5432...
FBgn0035847 mthl7
FBgn0032515 loqs
FBgn0266486 CG45085
FBgn0031359 CG18317
그런 다음 목록의 첫 번째 열에서 추출된 문자열을 검색하고 싶습니다.
추출된 문자열의 두 번째 열에 해당 값이 있으면 전체 ID를 바꾸고 싶습니다.intron_FBgnXXXXXX:X_FBgnXXXXXX:X두 번째 열에 해당 이름이 있습니다.
추출된 문자열이 첫 번째 열에 존재하지 않는 경우 전체 ID를 교체하고 싶습니다.인트론_XXXXXXXX:X_XXXXXXXX:X추출된 문자열로.
다음과 같은 스크립트가 있습니다.
ref="gene_map_table_fb_2014_01_short.tsv"
target="HC25_LNv_ZT02_intron_results.txt"
output="temptemp.txt"
declare -A map
while read line
do
if [[ ! -z "$line" ]] && [[ ! "$line" =~ ^#.* ]]
then
key=$(echo "$line" | cut -f 1)
value=$(echo "$line" | cut -f 2)
map[$key]=$value
fi
done < $ref
while read line
do
key=$(echo "$line" | sed -n 's/.*_\([^\.]*\)\:.*/\1/p' | head -1)
if [ ! -z "$key" ]
then
echo "$line" | sed 's/intron_[^[:space:]]*/'${map[$key]}'/g' >> $output
else
echo "$line" | sed 's/intron_[^[:space:]]*/'$key'/g' >> $output
fi
done < $target
출력 파일에 ID가 FBgn으로 시작하지 않는 줄이 없다는 점을 제외하면 모든 것이 잘 작동하는 것 같습니다.
답변1
할 수 있어요:
cat gene_map_table_fb_2014_01_short.tsv |sed '1d' |awk {'print $2'} |awk 'BEGIN{FS=":"} {print $2}' |sed s/._//g
먼저 파일을 분류한 다음 첫 번째 줄(d1이 포함된 열 헤더)을 삭제하고 모든 열을 인쇄한 다음 다음으로 분리한 다음 제거 4_FBgn0035847
합니다 awk 'BEGIN{FS=":"} {print $2}'
.number_
sed s/._//g
출력은 다음과 같습니다
FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359
CR31143
그러나 끝 줄이 추가되어 제거하려는 경우 다음과 같이 할 수 있습니다.
cat gene_map_table_fb_2014_01_short.tsv |sed '1d' |awk {'print $2'} |awk 'BEGIN{FS=":"} {print $2}' |sed s/._//g |sed '$d'
따라서 출력은 다음과 같습니다.
FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359
답변2
사용awk
그러면 탭으로 구분된 출력이 생성됩니다.
$ awk -v OFS="\t" 'NR==FNR{a[$1]=$2;next} FNR==1{print;next} {sub(/intron_/, "", $2); sub(/:.*/,"",$2);if ($2 in a) $2=a[$2];print}' gene_map_table_fb_2014_01_short.tsv HC25_LNv_ZT02_intron_results.txt
bundle_id target_id length eff_length tot_counts uniq_counts est_counts eff_counts ambig_distr_alpha ambig_distr_beta fpkm fpkm_conf_low fpkm_conf_high solvable tpm
1 mthl7 61 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
2 loqs 72 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
3 CG45085 58 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
4 CG18317 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
4 CG18317 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
4 CG18317 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
536 CR31143 40 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
설명:
-v OFS="\t"
그러면 출력 필드 구분 기호가 탭으로 만들어집니다.
NR==FNR{a[$1]=$2;next}
a
그러면 명령줄의 첫 번째 파일을 기반으로 첫 번째 열이 키이고 두 번째 열이 값인 연관 배열이 생성됩니다 . 이next
명령은awk
나머지 명령을 건너뛰고 다음 줄로 이동하도록 지시합니다.매핑 파일에는 몇 가지 주석 줄이 포함되어 있습니다.
if
배열에 추가되는 것을 방지하기 위해 추가 명령문을 쉽게 추가할 수 있었습니다a
. 그러나 해를 끼치지 않기 때문에 우리는 그 합병증을 건너뛰었습니다.FNR==1{print;next}
이렇게 하면 헤더 줄이 변경되지 않고 인쇄됩니다.
{sub(/intron_/, "", $2); sub(/:.*/,"",$2)
이렇게 하면 두 번째 필드에서 보풀이 제거되고 우리가 원하는 문자열만 남게 됩니다.
`if ($2 in a) $2=a[$2]
두 번째 필드의 문자열이 array의 키로 존재하는 경우
a
해당 값을 대체합니다.print
수정된 라인이 인쇄됩니다.
사용bash
스크립트에서 교체
if [ ! -z "$key" ]
와 함께:
if [[ "$key" && "${map[$key]}" ]]
이 시점에서 스크립트가 알아야 할 것은 key
존재 map
여부입니다. 수정된 테스트에서는 해당 항목이 key
비어 있지 않을 뿐만 아니라 map
.
한 가지만 변경하면 다음과 같은 결과를 얻습니다.
$ cat temptemp.txt
bundle_id target_id length eff_length tot_counts uniq_counts est_counts eff_counts ambig_distr_alpha ambig_distr_beta fpkm fpkm_conf_low fpkm_conf_high solvable tpm
1 mthl7 61 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
2 loqs 72 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
3 CG45085 58 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
4 CG18317 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
4 CG18317 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
4 CG18317 4978 1430.739479 91 0 30.333333 105.539363 1.00E+00 1.00E+00 6.30E+00 1.77E+00 1.08E+01 F 1.42E+01
536 CR31143 40 0 0 0 0 0 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 F 0.00E+00
별도로 on 은 text
비어 있지 않으면 [ ! -z "$key" ]
true를 반환합니다 key
. 이는 와 동일합니다 [ -n "$key" ]
. 이는 매우 일반적인 테스트이므로 로 더욱 축약될 수 있습니다 [ "$key" ]
. 이는 스크립트의 여러 줄을 단순화하는 데 사용될 수 있습니다 bash
.