여러 파일의 줄을 새 파일로 복사하고 파일 이름을 유지하는 방법은 무엇입니까?

여러 파일의 줄을 새 파일로 복사하고 파일 이름을 유지하는 방법은 무엇입니까?

(최대) 53개의 프로젝트를 포함하는 .fasta 형식의 81개 파일이 있습니다. 예를 들어:

/User/MyData/Sample_1.fasta
/User/MyData/Sample_2.fasta
....
/User/MyData/Sample_81.fasta

각 .fasta 파일에는 다음으로 구분된 이름 ID와 문자열이 포함되어 있습니다.

>AT1G00001
ATCCACTGCTGTGTACCTGATCAGTGCTGACCCAYTGTGACACTGTG
>AT2G00002
AAAAATTTTGCCCGTGTGGGCCAAACTGTCATGCATGCACCGTACGTGCATGCAT
....
>ATXGXXXXX(up to 53)
AAACCCTCTTTGTGCCTGTGCATGCA

81개의 .fasta 파일에 있는 각 문자열을 새 .fasta 파일에 복사하여 다음과 같이 하려고 합니다.

/User/MyData/AT1G00001.fasta
/User/MyData/AT2G00002.fasta
....
/User/MyData/ATXGXXXXX.fasta

그 중 하나의 콘텐츠에는 다음이 포함됩니다(디렉토리의 모든 "Sample_X.fasta" 파일에서 복사한 후).

>Sample_1
ATCCACTGCTGTGTACCTGATCAGTGCTGACCCAYTGTGACACTGTG
>Sample_2
ATCGACTCCCGTAGGACTGATTTTTCTGACCCCATTGTGACACTGTG
....
>Sample_81
TTCTGACCCCATTGTGACACTGTGATCGACTCCCGTAGGACTGATTT

한두 가지 유사한 문제에 직면했지만 복사된 출력 파일에서 SampleName을 유지하는 미묘한 차이에는 거의 차이가 없으며 유사하지만 다른 문제에서 샘플을 얻는 데 약간의 어려움이 있습니다.

도와주셔서 감사합니다!

답변1

다음 코드가 있습니다. 아래에 작동 방식에 대한 설명이 있습니다.

먼저 작업 디렉터리( cd /User/MyData/)를 입력하고 프로그램을 실행합니다.

awk '
  FNR==1 { sample = FILENAME ; sub(/\.fasta/, "", sample }
  /^>/   { target = substr($0,2)".fasta" ; next }
         { print ">" sample > target ; print > target }
' Sample_*.fasta

프로그램 awk은 모든 파일을 반복합니다 Sample_*.fasta. 각 입력 파일( )의 시작 부분에서 FNR==1접미사 ".fasta"를 제거하여 현재 파일 이름에서 샘플 이름을 추출합니다. 줄이 로 시작하는 경우 >레코드의 대상 파일 이름은 >해당 문자 뒤에 파일 이름 접미사 ".fasta"가 추가되어 사용됩니다. 다른 유형의 행의 경우 이전에 추출된 샘플 이름이 대상 파일에 기록되고 현재 데이터가 두 번째 행에 기록됩니다.

참고: "열린 파일 설명자가 너무 많음" 문제를 발견한 경우 가장 좋은 옵션은 GNU로 전환하는 것입니다( awk가능한 경우)!

귀하의 플랫폼에서 GNU를 awk사용할 수 없거나 사용할 수 없는 경우 몇 가지 추가 변경이 필요합니다. 중요한 것은 각 파일에 쓴 후 닫는 기능을 사용하는 것입니다 close(). 결과는 닫힌 파일에 추가되어야 합니다. . (이것은 더 복잡하고 성능이 떨어지므로 GNU를 구하고 awk첫 번째 변형을 사용하는 것을 고려해 볼 가치가 있습니다 .)

이러한 변경으로 인해 다음과 같은 프로그램이 생성됩니다.

# because of the append operation you need to empty the file targets
# before calling subsequent awk code, e.g. by: rm -f AT???????.fasta
awk '
  FNR==1 { sample = FILENAME ; sub(/\.fasta/, "", sample }
  /^>/   { target = substr($0,2)".fasta" ; next }
         { printf ">%s\n%s\n", sample, %0 >> target ; close(target) }
' Sample_*.fasta

awk프로그램을 호출하기 전에 기존 출력 파일이 삭제되거나 이전 호출에서 지워졌는지 확인해야 합니다. 그렇지 않으면 새 출력이 이전에 해당 출력 파일에 존재했던 데이터에 추가됩니다.

답변2

지금까지 무엇을 시도했는지 알아보는 것도 흥미로울 수 있지만, awk이것이 어떻게 작동하는지에 대한 예는 다음과 같습니다.

awk '
    FNR == 1 {
        sub(/\.fasta$/, "", FILENAME)
    }
    /^>/ && sub(/^>/, "") {
        newfile = $0 ".fasta"
        next
    }
    {
        print ">" FILENAME >> newfile
        print $0 >> newfile
    }' Sample_*.fasta

답변3

일부 쉘: awk 프로그램보다 훨씬 느립니다.

cd /User/MyData
for sample in Sample*.fasta; do
    sample_name=${sample%.fasta}
    while read name; read data; do
        name=${name#>}
        printf ">%s\n%s\n" "$sample_name" "$data" >> "$name.fasta"
    done < "$sample"
done

관련 정보