다음 문제에 대해 도움을 줄 수 있는 사람이 있나요? 나는 약 40개의 서로 다른 종의 디렉터리를 가지고 있으며, 각 디렉터리에는 직교 서열을 포함하는 수백 개의 서열 파일이 있습니다. 시퀀스 파일은 각 종 디렉토리에 대해 유사하게 이름이 지정됩니다. 나는 40종 디렉토리의 동일한 이름의 파일을 비슷한 이름의 단일 시퀀스 파일로 연결하고 싶습니다.
예를 들어 "Species1", "Species2", "Species3"이라는 3개의 디렉토리가 있습니다. 이러한 디렉터리 내에는 "SequenceA.fasta", "SequenceB.fasta", "SequenceC.fasta"와 같은 유사한 이름의 파일이 있습니다. 다른 SequenceA.fasta 파일의 모든 내용을 다른 디렉터리에 있는 "SequenceA.fasta"라는 이름의 새 파일 하나로 연결해야 합니다. 어떻게 해야 하나요?
다음 루프로 시도했지만 실패했습니다. 파일이 생성되었지만 비어 있습니다.
ls . | while read FILE; do cat ./*/"$FILE" >> ./final/"$FILE"; done
조언이나 도움을 주셔서 감사합니다!
(교차 게시 가능성이 있어 죄송합니다. 이전에 실수로 잘못된 포럼에 이 질문을 게시했습니다.)
답변1
이 답변에는 몇 가지 참고할 사항이 있습니다.
ls
대신 쉘glob
패턴을 사용하여 원하는 작업을 수행 할 수 있는 경우 출력을 구문 분석하는 것은 일반적으로 좋지 않은 생각입니다 .http://mywiki.wooledge.org/ParsingLs]. 이식성을 위해 nullglob 쉘 옵션을 사용하지 않았지만 그렇게 하면 스크립트가 약간 더 짧아질 것입니다.glob 패턴이 너무 광범위하지 않은지 확인하여
cat
입력과 출력 모두에 동일한 파일 이름을 사용하도록 지시합니다. 그렇게 하면 무한한 크기의 파일을 생성하려고 시도할 때 하드 드라이브가 매우 빨리 채워질 수 있습니다.다음과 같은 패턴을 제공했는데
*.fasta
어떤 파일과도 일치하지 않으면 리터럴 문자열이*.fasta
사용됩니다.호출된 파일이 있는 경우
*.fasta
해당 파일과 패턴의 차이를 구분하는 한 가지 방법은 읽을 수 있는지 확인하는 것입니다.악성 파일 이름이 있을 수 있는 경우 인수 구문 분석을 종료
--
하는 것이 좋습니다.
먼저 간단한 스크립트입니다.
# Simple script, assumes that "Species1" has all the needed "SequenceX.fasta" files
# Start in the directory containing "Species1", "Species2" etc.
# create output directory
mkdir "final"
# Go into the first directory
cd "Species1"
# Loop over all the files
for i in *".fasta"
do
# join all the like named files in the sibling directories to the output
# use a pattern which doesn't match ../final/$i to get list of files to join.
cat "../Species"*"/$i" > "../final/$i"
done
이는 "Species1"에 모든 "SequenceX.fasta" 파일이 있다고 가정합니다. 그렇지 않은 경우 이중 루프가 필요할 수 있습니다. 이는 더 강력하지만 더 길고 느립니다.
# Start in the top level and loop over the directories
for dir in */
do
# don't do anything inn the output directory
[ "$dir" = "final" ] && continue
# cd into directory, protecting against rogue directory names
cd "./$dir" || { echo "cd to $dir failed" >&2 ; exit 1 ; }
# loop over the files
for file in *"fasta"
do
# check the file exists, if there are no files matching the pattern
# then the shell will pass the pattern through to the loop
if [ -r "$file" ] ; then
cat -- "$file" >> "../final/$file"
fi
done
cd ".." || { echo "failed to return from $dir" ; exit 1 ; }
done