일련의 폴더에 일련의 파일이 있습니다. 예를 들면 다음과 같습니다.
~/BR2_1-3/bin.1.permissive.tsv
~/BR2_1-3/bin.2.permissive.tsv
~/BR2_1-3/bin.3.orig.tsv
~/BR2_2-4/bin.1.strict.tsv
~/BR2_2-4/bin.2.orig.tsv
~/BR2_2-4/bin.3.permissive.tsv
~/BR2_2-4/bin.4.permissive.tsv
~/BR2_3-5/bin.1.permissive.tsv
~/BR2_3-5/bin.2.permissive.tsv
~/BR2_3-5/bin.3.orig.tsv
~/BR2_3-5/bin.4.orig.tsv
~/BR2_3-5/bin.5.permissive.tsv
...
내가 원하는 것은 각 *.tsv 파일에서 첫 번째와 다섯 번째 열을 추출하고 해당 폴더에 탭으로 구분된 새 파일을 만드는 것입니다. 다음을 사용하여 해당 폴더 아래의 각 파일에 대해 개별적으로 이 작업을 수행할 수 있습니다.
$ awk -F '\t' 'OFS="\t" {if ($5 != "") print($1,$5)}' bin.1.permissive.tsv > test
$ sed -i '1d' test
$ mv test BR2_1-bin.1.permissive.ec
제 질문은 이러한 파일이 100개 이상 있으므로 for
터미널에서 이 단계를 자동으로 수행하도록 루프를 작성하는 방법이 있습니까? 입니다.
폴더 및 파일의 명명 규칙은 다음과 같습니다. 폴더는 "BR(2~5)_(1~6)-(n, 폴더에 포함된 파일 수)"입니다. / 허용/원본).tsv”.
입력 파일은 출력 파일에 매핑되어야 합니다. 해당 입력 파일이 "~/BR2_1-3/bin.1.permissive.tsv"인 경우 출력 파일 이름은 "BR2_1-bin.1.permissive.ec"입니다. 해당 입력 파일이 "~/BR2_3-5/bin.3.orig.tsv"인 경우 출력 파일 이름은 "BR2_3-bin.3.orig.ec"입니다. 또한 출력 파일은 해당 입력 파일과 동일한 폴더에 기록되어야 합니다. 댓글로 이런 질문을 해주셔서 감사합니다.
미리 감사드리며 모든 제안을 환영합니다!
답변1
find
일반적으로 xargs
다음을 수행하는 것이 좋습니다.
find "$HOME" -name \*.tsv |
xargs awk -F'\t' -v OFS='\t' '$5 != "" {print $1, $5}' >> output.tsv
아니면 좀 더 안전하게
find "$HOME" -name \*.tsv -print0 |
xargs -0 awk -F'\t' -v OFS='\t' '$5 != "" {print $1, $5}' >> output.tsv
find -print0
명령은 널 바이트로 구분된 일치하는 파일을 인쇄하고 xargs -0
옵션은 널 바이트를 사용하여 파일 이름을 구분합니다. 이는 파일 이름에 널 바이트가 허용되지 않고 개행 문자가 유효한 문자이기 때문에 수행됩니다.
좋습니다. 각 파일은 해당 .ec
파일로 처리되어야 합니다.
find "$HOME" -name \*.tsv -print0 |
xargs -0 awk -F '\t' -v OFS='\t' '
FNR == 1 {
if (ec) close(ec)
ec = gensub(/\.tsv$/, ".ec", 1, FILENAME)
next
}
$5 != "" {print $1, $5 > ec}
'
노트:
print ... > ex
- 셸의 리디렉션과 유사하게 출력을 변수에 포함된 파일 이름으로 리디렉션합니다ec
.- 셸과 달리 이는 각 "인쇄"에 대해 파일을 덮어쓰지 않지만 첫 번째 인쇄만 파일을 자르거나 생성하며 모든 후속 인쇄는 파일에 추가됩니다.
close
"열린 파일이 너무 많습니다"라는 오류가 발생할 수 있으므로 파일 사용이 끝날 때까지 기다렸다가 여는 것이 가장 좋습니다 .- 파일의 첫 번째 레코드에 있을 때 이 작업을 수행하십시오.
- 변수가 비어 있지 않으면
ec
다음 기간 동안 저장됩니다.더 일찍처리된 파일
gensub
sub
및 와 유사한 gawk 특정 기능입니다gsub
. 그것은설명서에 설명된sub
및 와는 다릅니다gsub
.gensub
반품변환된 값입니다.