![문자열 추출, 검색 및 바꾸기 또는 추출된 값이 포함된 긴 문자열 유지](https://linux55.com/image/57267/%EB%AC%B8%EC%9E%90%EC%97%B4%20%EC%B6%94%EC%B6%9C%2C%20%EA%B2%80%EC%83%89%20%EB%B0%8F%20%EB%B0%94%EA%BE%B8%EA%B8%B0%20%EB%98%90%EB%8A%94%20%EC%B6%94%EC%B6%9C%EB%90%9C%20%EA%B0%92%EC%9D%B4%20%ED%8F%AC%ED%95%A8%EB%90%9C%20%EA%B8%B4%20%EB%AC%B8%EC%9E%90%EC%97%B4%20%EC%9C%A0%EC%A7%80.png)
편집해야 하는 입력 파일은 다음과 같습니다(라인이 더 많을 수 있음).
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에 대해Intron_XXXXXXXX:X_XXXXXXXX:X, 사이의 문자열을 추출하고 싶습니다인트론_그리고 첫 번째:(문자열 사이는 일반적으로 FBgn으로 시작하지만 항상 그런 것은 아닙니다).
그런 다음 다음과 같은 목록이 있습니다.FBGN그리고 FBgn을 변환하려는 해당 이름을 가진 다른 열:
## 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를 교체하고 싶습니다.Intron_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
출력 파일에 FBgn으로 시작하지 않는 ID가 포함된 줄이 누락된 점을 제외하면 모든 것이 잘 작동하는 것 같습니다.
답변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)
이렇게 하면 두 번째 필드의 초과 내용이 제거되고 원하는 문자열만 남습니다.
`만약 ($2 in a)$2=a[$2]
두 번째 필드의 문자열이 배열의 키로 존재하는 경우
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
aside 로 text
null이 아닌 경우 [ ! -z "$key" ]
true를 반환합니다 . key
이는 [ -n "$key" ]
일반적인 테스트이므로 로 더 단축할 수 있습니다 [ "$key" ]
. 이는 bash
스크립트의 몇 줄을 단순화하는 데 사용할 수 있습니다 .