2014-05-14 4 views
1

최상위 디렉토리에서 각 하위 디렉토리를 입력하고 몇 개의 디렉토리를 만들고 하위 디렉토리의 각 파일에 명령을 실행 한 다음 이름을 바꾸고 이동하는 스크립트를 만들려고합니다. 파일들. 나는 수천 개의 디렉토리에서 실행되어야하기 때문에 디렉토리 나 다른 이름의 이름을주는 것과 같은 추가적인 입력없이이 작업을 수행해야합니다. 이것은 내가 정말 실제로 이해하지 못하는 내가 쓴 스크립트입니다 :하위 디렉토리를 반복적으로 이동하여 모든 파일에 대해 명령을 실행합니다.

#!/bin/bash 
for path in ./*; 
do 
[ -d "${path}" ] || continue 
dirname="$(basename "${path}")" 
cd $path 
mkdir stats 
mkdir dir 
files=(./*) 
for f in "${files[@]}" 
do 
do stuff 
done 
cd dir 
mkdir stats 
mv *.trimmed_segments* stats/ 
rename '.fastq.trimmed' '.fastq' ./* 
cd .. 
mkdir raw 
mv *.fastq raw/ 
mv trimmed/*.fastq ./ 
cd .. 
done 

그것은 이상하게도, 몇 하위 디렉토리에 제대로 작동하고 밖으로 프리츠와 펄에 대한 오류의 무리를 보내기 시작합니다 상당히 특이하지 않은 스크립트.

명령 자체는 괜찮습니다. 폴더에 들어가서 수동으로 입력해도 아무런 문제가 없으므로 올바른 변수를 던지는 데 문제가 있습니다. 내 실수를 볼 수 있다면 정말 고맙겠습니다.

+0

오류가 perl에서 발생하는 경우 오류 및 스크립트 자체를 게시하는 것이 도움이됩니다. – Cfreak

+0

스크립트는 solexaqa, solexaqa.pl 및 dynamictrim.pl에서 나는 충분히 구체적이지 않았습니다, 그들은 'do stuff'의 일부입니다. 오류는 매번 다르지만이 일반적인 프레임 워크에 속합니다. 해시 요소 (또는 초기화되지 않은 다른 값 사용)에서 초기화되지 않은 값 $ tile_number 사용. 그러나 오류는 필자가 펄에서 올바른 변수를 보내지 않는 스크립트에서 오는 펄에서 실제로 오지는 않는다. – user2472414

+0

훨씬 간단한 스크립트! Simulans_next_gen/* CD의 난에 대한/빈/bash는 $ 내가 에서 mkdir이 펄 빈/SolexaQA_v.2.2/SolexaQA 트림 에서 mkdir Solexa_Stats.pl * -d Solexa_Stats; perl bin/SolexaQA_v.2.2/DynamicTrim.pl * .fq -d trimmed -sanger; done은 초기화되지 않은 변수가 다르더라도 동일한 문제가 있습니다. – user2472414

답변

0

나는 이것이 본질적으로 답이라고 생각하지 않지만, 당신과 미래의 답변자들이 디버그하는데 도움이 될 것이며, 충분한 다른 정보가 있다면 그것을 업데이트 할 것입니다. 당신이 고려하는 것이 좋습니다

#!/bin/bash 
for path in ./*; do 
    [ -d "${path}" ] || continue 
    dirname="$(basename "${path}")" 
    cd $path        # origin/$path 
    mkdir stats       # (this seems not to be used) 
    mkdir dir 
    files=(./*) 
    for f in "${files[@]}"; do 
    # do stuff 
    done 
    cd dir         # origin/$path/dir 
    mkdir stats 
    mv *.trimmed_segments* stats/ 
    rename '.fastq.trimmed' '.fastq' ./* 
    cd ..         # origin/$path 
    mkdir raw 
    mv *.fastq raw/ 
    mv trimmed/*.fastq ./ 
    cd ..         # origin 
done 

한 기술은 또한 작업 디렉토리를 변경 캡슐화되는, grouping commands to create subshells()을 사용하는 것입니다

여기 들여 쓰기 및 의견 스크립트입니다. 그것이 그대로, 당신은 cd와 함께 많은 상대 경로를 사용하며, 그것은 당신이 어디에 있는지 정확히 알기 어렵게 만들 수 있습니다. 특히 명령이 실패 할 경우 특히 그렇습니다. (이를 위해 도움이 될 수 있습니다 오류 코드와 어떤 명령이 종료됩니다, 당신은 오류가 발생할 경우 확인되면 즉시 종료 set -e를 사용합니다.)

#!/bin/bash 
set -e         # fail immediately on error 
for path in ./*; do 
    [ -d "${path}" ] || continue 
    dirname="$(basename "${path}")" 
    (
    cd $path        # origin/$dirname 
    mkdir stats 
    mkdir dir 
    files=(./*) 
    for f in "${files[@]}"; do 
     # do stuff 
    done 
    (
     cd dir        # origin/$dirname/dir 
     mkdir stats 
     mv *.trimmed_segments* stats/ 
     rename '.fastq.trimmed' '.fastq' ./* 
    ) 
    mkdir raw 
    mv *.fastq raw/ 
    mv trimmed/*.fastq ./ 
) 
done 
0

또 다른 기술을이 임의의 깊이의 나무 인 경우에하는 수 있도록 함수를 호출하고 재귀 적으로 호출합니다 (즉, 내부에서부터 시작하여 매번 완료되면 호출 된 위치로 되돌아갑니다).

는 사실이 시도하지 않은,하지만 같이 보일 것입니다 :

processDir() { 
    cd "$1" 
    # it's a directory, so what you need to for a directory here 
    # ... 
    for path in ./*; do 
     if [[ -d "${path}" ]]; then 
      processDir "${path}" 
     else 
      # it's a file, not a dir, so do file operations here, if any 
      # ... 
     fi 
    done 
} 

processDir yourStartDirectory 
1

당신이 간부 옵션을 찾을 수 사용으로 간주 있나요?

저는 일반적으로 경로를 "걸어 가야"할 때 사용합니다.

적합하다고 판단되는 최소/최대 깊이 값으로 재생하십시오. 일련의 명령을 실행할 스크립트를 실행할 수도 있습니다.

#Directories 
find ./ -mindepth 1 -maxdepth 1 -type d -exec bash -c 'mkdir {}/stats; mkdir {}/dir' \; 

#Files 
find ./ -maxdepth 1 -type f -exec bash -c 'commands here...' \;