기본적으로 주소로 대체되도록 $1
( cat
파일 뒤의) 변수를 복사하여 대체해야 합니다 . 내 시도는 다음과 같습니다.sample
/disk1/ngsep/"$sample"/"$1"_bowtie2_readpos.stats
cat samples_long.10ids.txt | awk -v sample="$1" '{gsub(/_USD.*/,"",sample); print $sample,$1}'
다음을 생성합니다.
P2_142_USD16089440L_HJM27DSXX_L3 P2_142_USD16089440L_HJM27DSXX_L3
P2_144_USD16089441L_HJM27DSXX_L3 P2_144_USD16089441L_HJM27DSXX_L3
P2_145_USD16089442L_HJM27DSXX_L3 P2_145_USD16089442L_HJM27DSXX_L3
P2_168_USD16089450L_HJM27DSXX_L3 P2_168_USD16089450L_HJM27DSXX_L3
P2_171_USD16089451L_HJM27DSXX_L4 P2_171_USD16089451L_HJM27DSXX_L4
P2_172_USD16089452L_HJM27DSXX_L4 P2_172_USD16089452L_HJM27DSXX_L4
P2_188_USD16089456L_HJM27DSXX_L4 P2_188_USD16089456L_HJM27DSXX_L4
P2_262_USD16089477L_HJJNWDSXX_L2 P2_262_USD16089477L_HJJNWDSXX_L2
P2_270_USD16089479L_HJJNWDSXX_L2 P2_270_USD16089479L_HJJNWDSXX_L2
P2_271_USD16089480L_HJJNWDSXX_L4 P2_271_USD16089480L_HJJNWDSXX_L4
하지만 나는 다음이 필요합니다:
P2_142 P2_142_USD16089440L_HJM27DSXX_L3
P2_144 P2_144_USD16089441L_HJM27DSXX_L3
P2_145 P2_145_USD16089442L_HJM27DSXX_L3
P2_168 P2_168_USD16089450L_HJM27DSXX_L3
P2_171 P2_171_USD16089451L_HJM27DSXX_L4
P2_172 P2_172_USD16089452L_HJM27DSXX_L4
P2_188 P2_188_USD16089456L_HJM27DSXX_L4
P2_262 P2_262_USD16089477L_HJJNWDSXX_L2
P2_270 P2_270_USD16089479L_HJJNWDSXX_L2
P2_271 P2_271_USD16089480L_HJJNWDSXX_L4
더 긴 파이프라인에서 사용하려면 다음 안내를 따르세요.
cat samples_long.10ids.txt |
cat `awk -v sample="$1" 'BEGIN {gsub(/_USD.*/,"",sample); print "/disk1/ngsep/"$sample"/"$1"_bowtie2_readpos.stats"}'` |
awk '{if(NR<151) {print $1,$2,$3,$4,$5,$3/$5*100} else {print $0}}' |
less
고쳐 쓰다
@cas의 답변 덕분에 제대로 작동할 수 있었습니다. 파이프라인을 더 길게 변경했습니다.
tail -n +1 `awk '{sample=$1; gsub(/_USD.*/,"",sample); print "/disk1/ngsep/"sample"/"$1"_bowtie2_readpos.stats"}' samples_long.10ids.txt` | awk 'm=($1 ~ /^[0-9]+$/) {print $0,$3/$5*100.0} !m {print $0}' | awk 'm=($1 == "==>") {save_location=$2} !m&&$1=="1",$1=="Bases" {print > save_location}'
설명하다:
먼저, 다음 형식의 여러 파일이 서로 다른 위치에 있습니다.
1 44270430 2888669 939293704 101672177
2 39504262 2535442 939293704 101672177
3 36179652 2298760 939293704 101672177
4 35187362 2216378 939293704 101672177
5 31718310 1957024 939293704 101672177
...
145 30614327 2148102 939293704 101672177
146 31053766 2211019 939293704 101672177
147 33769500 2475193 939293704 101672177
148 34799685 2574711 939293704 101672177
149 38192883 2761700 939293704 101672177
150 41098709 2974392 939293704 101672177
Alignments 939293704 101672177
Bases 140205023688 15190431468
3열을 5열로 나누고 100을 곱하여 6열로 저장하는 연산을 하고 싶습니다. 결과:
1 44270430 2888669 939293704 101672177 2.84116
2 39504262 2535442 939293704 101672177 2.49374
3 36179652 2298760 939293704 101672177 2.26095
4 35187362 2216378 939293704 101672177 2.17993
5 31718310 1957024 939293704 101672177 1.92484
...
145 30614327 2148102 939293704 101672177 2.11277
146 31053766 2211019 939293704 101672177 2.17465
147 33769500 2475193 939293704 101672177 2.43448
148 34799685 2574711 939293704 101672177 2.53237
149 38192883 2761700 939293704 101672177 2.71628
150 41098709 2974392 939293704 101672177 2.92547
Alignments 939293704 101672177
Bases 140205023688 15190431468
이제 더 긴 명령어를 설명하겠습니다.
`awk '{sample=$1; gsub(/_USD.*/,"",sample); print "/disk1/ngsep/"sample"/"$1"_bowtie2_readpos.stats"}' samples_long.10ids.txt` |
그렇기 때문에 samples_long.10ids.txt
. P2_142
결과:
/disk1/ngsep/P2_142/P2_142_USD16089440L_HJM27DSXX_L3_bowtie2_readpos.stats
/disk1/ngsep/P2_144/P2_144_USD16089441L_HJM27DSXX_L3_bowtie2_readpos.stats
/disk1/ngsep/P2_145/P2_145_USD16089442L_HJM27DSXX_L3_bowtie2_readpos.stats
/disk1/ngsep/P2_168/P2_168_USD16089450L_HJM27DSXX_L3_bowtie2_readpos.stats
/disk1/ngsep/P2_171/P2_171_USD16089451L_HJM27DSXX_L4_bowtie2_readpos.stats
...
tail -n +1
:인쇄된 주소에 해당하는 모든 파일(표준 출력)을 읽고 awk
해당 위치를 추가해야 하기 때문에 이 방법을 사용합니다. 결과:
==> /disk1/ngsep/P2_142/P2_142_USD16089440L_HJM27DSXX_L3_bowtie2_readpos.stats <==
1 37000568 2614993 747883433 76303046
2 33228316 2330791 747883433 76303046
...
149 33852828 2660530 747883433 76303046
150 36161756 2836045 747883433 76303046
Alignments 747883433 76303046
Bases 111613795461 11392665612
==> /disk1/ngsep/P2_144/P2_144_USD16089441L_HJM27DSXX_L3_bowtie2_readpos.stats <==
1 40000373 2754292 838333186 82982133
2 35955786 2451917 838333186 82982133
...
awk 'm=($1 ~ /^[0-9]+$/) {print $0,$3/$5*100.0} !m {print $0}' |
여기서는 $1이 숫자와 일치하는 경우에만 인쇄하고, 일치하지 않으면 아무 작업도 하지 않고 전체 줄을 인쇄합니다. 결과:
==> /disk1/ngsep/P2_142/P2_142_USD16089440L_HJM27DSXX_L3_bowtie2_readpos.stats <==
1 37000568 2614993 747883433 76303046 3.42711
2 33228316 2330791 747883433 76303046 3.05465
...
149 33852828 2660530 747883433 76303046 3.48679
150 36161756 2836045 747883433 76303046 3.71682
Alignments 747883433 76303046
Bases 111613795461 11392665612
==> /disk1/ngsep/P2_144/P2_144_USD16089441L_HJM27DSXX_L3_bowtie2_readpos.stats <==
1 40000373 2754292 838333186 82982133 3.31914
2 35955786 2451917 838333186 82982133 2.95475
...
awk 'm=($1 == "==>") {save_location=$2} !m&&$1=="1",$1=="Bases" {print > save_location}'
작업을 수행한 후 각 해당 파일을 특정 디렉터리에 저장해야 합니다. 따라서 사용하면 tail -n +1
출력 사이 ==>
에 파일 위치를 추가한 다음 if 에 할당하여 해당 위치를 변수에 저장합니다 . 그렇지 않은 경우 패턴 사이의 나머지 부분을 가리키는 주소 에 저장합니다 . 예제에 해당하는 파일을 예로 들어 보겠습니다.<==
save_location
$2
$1=="==>"
1
Bases
save_location
P2_142
1 37000568 2614993 747883433 76303046 3.42711
2 33228316 2330791 747883433 76303046 3.05465
3 30544208 2130666 747883433 76303046 2.79237
4 29727794 2059047 747883433 76303046 2.69851
5 26873913 1825829 747883433 76303046 2.39287
...
145 27262253 2093226 747883433 76303046 2.74331
146 27992017 2188217 747883433 76303046 2.8678
147 30385435 2433407 747883433 76303046 3.18913
148 31218703 2514902 747883433 76303046 3.29594
149 33852828 2660530 747883433 76303046 3.48679
150 36161756 2836045 747883433 76303046 3.71682
Alignments 747883433 76303046
Bases 111613795461 11392665612
답변1
이 작업은 sed를 사용하여 쉽게 수행할 수 있습니다.
$ sed -E -e 's/^((.*)_USD.*)/\2 \1/' input.txt
P2_142 P2_142_USD16089440L_HJM27DSXX_L3
P2_144 P2_144_USD16089441L_HJM27DSXX_L3
P2_145 P2_145_USD16089442L_HJM27DSXX_L3
P2_168 P2_168_USD16089450L_HJM27DSXX_L3
P2_171 P2_171_USD16089451L_HJM27DSXX_L4
P2_172 P2_172_USD16089452L_HJM27DSXX_L4
P2_188 P2_188_USD16089456L_HJM27DSXX_L4
P2_262 P2_262_USD16089477L_HJJNWDSXX_L2
P2_270 P2_270_USD16089479L_HJJNWDSXX_L2
P2_271 P2_271_USD16089480L_HJJNWDSXX_L4
sed 스크립트는 두 개의 캡처 그룹, (
즉 및로 둘러싸인 정규식 패턴을 사용합니다 )
. 첫 번째는 전체 입력 라인이고, 두 번째는 이전 라인의 첫 번째 부분입니다 _USD
. 각 입력 줄을 두 번째 캡처링 그룹( \2
), 공백으로 바꾼 다음 첫 번째 캡처링 그룹( )으로 바꿉니다 \1
.
또는 다음을 사용하여 awk
:
awk -F'_' -e '{print $1 "_" $2 " " $0}' input.txt
입력 필드 구분 기호를 로 설정한 _
다음 (각 입력 줄에 대해) 밑줄과 공백을 사용하여 처음 두 필드를 인쇄한 다음 전체 입력 줄을 인쇄합니다.
명령에 몇 가지 문제가 있습니다.
cat samples_long.10ids.txt | \
awk -v sample="$1" '{gsub(/_USD.*/,"",sample); print $sample,$1}'
파일을 awk로 파이프하기 위해 cat이 필요하지 않습니다. awk는 명령줄에서 인수로 제공된 파일 이름을 읽을 수 있습니다.
awk 변수를
sample
"$1"로 설정하고 있습니다. 일부 (표시되지 않음) 쉘 스크립트 래퍼의 첫 번째 매개 변수가 아니라 awk의 첫 번째 필드를 의미한다고 생각합니다. 그건 작동하지 않습니다.$1
awk는 쉘에 존재하지 않습니다. awk가 입력 데이터 행을 읽을 때만 존재합니다.필드 구분 기호로 무엇을 사용해야 하는지 awk에 알려주지 않았으므로 기본값은 공백(공백 및 탭)입니다. 예제 입력에는 공백 문자가 없으므로 $1 은 전체 입력 줄( $1 이라고 함
$0
)입니다."$sample"을 인쇄 중입니다. 이는 변수에 포함된 필드 번호를 인쇄하고 싶다는 것을 awk에 알려줍니다
sample
.sample
문자열을 포함하므로0
해당 컨텍스트에서print $sample
-equivalent 로 평가됩니다printing $0
. 따라서 코드는 유효합니다print $0 $1
. 이것은 작동합니다print $0 $0
. 전체 줄을 두 번 인쇄합니다.sample
(계산된 결과의 필드 번호가 아닌sample
) 내용 자체를 인쇄하려면print sample
.4번과 5번 항목에는 더 많은 설명이 필요하거나 최소한 더 이해하기 쉬운 예가 필요할 수 있습니다.
NF
awk가 입력 라인을 읽을 때마다 라인의 필드 수 라는 변수를 자동으로 설정합니다 .필드 수를 인쇄하려면 을 인쇄하면 됩니다
NF
. 필드 번호가 NF와 같은 필드를 인쇄하려면 인쇄하십시오$NF
(이렇게 하면 입력 행의 마지막 필드가 인쇄됩니다).NF(정수)에 대해 산술 및 기타 연산을 수행할 수도 있습니다. 예를 들어
print $(NF-1)
마지막에서 두 번째 필드가 인쇄됩니다.코드로 돌아가서,
$sample
정수 컨텍스트에는sample
값이 있으므로 전체 입력 줄인 을0
인쇄했습니다 .$0
위의 모든 사항을 고려하면 다음과 같이 작동합니다.
awk '{sample=$1; gsub(/_USD.*/,"",sample); print sample,$1}' samples_long.10ids.txt
하지만 이렇게 간단한 작업을 수행하기에는 너무 복잡합니다. awk는 입력을 밑줄로 구분된 필드로 분할할 수 있으므로 이를 수행하는 것이 더 쉽습니다.
awk -F'_' -e '{print $1 "_" $2 " " $0}' samples_long.10ids.txt
답변2
신인의 awk
실수...
awk
파일을 매개변수로 전달합니다.
gawk [POSIX 또는 GNU 스타일 옵션] [ -- ] 프로그램 텍스트문서...