여러 파일에 대해 명령을 실행하고 각 출력에 고유한 이름을 지정합니다.

여러 파일에 대해 명령을 실행하고 각 출력에 고유한 이름을 지정합니다.

다음과 같이 폴더의 모든 파일에 대해 스크립트를 실행하고 싶습니다.

sh script.sh *.fasta > output

하지만 각 입력의 출력이 별도의 파일에 있기를 원합니다. 그렇다면 명령을 통해 5개의 파일을 가져와 "output"이라는 파일에 모두 넣는 대신 출력을 파일 이름으로 만들고 끝에 "_output"과 같은 접미사를 추가하는 방법이 있습니까?

따라서 다음과 같은 3개의 파일이 있는 경우:

file1.fasta
file2.fasta
file3.fasta

다음과 같은 명령을 실행할 수 있는 방법이 있습니까?

sh script.sh *.fasta

그리고 각 입력에 대해 다음과 같은 새 파일을 출력합니다.

file1_new.fasta
file2_new.fasta
file3_new.fasta

나는 다음 명령을 시도했습니다.

sh script.sh *.fasta > *_output.fasta

하지만 작동하지 않습니다. 관심 있는 모든 파일을 이와 같은 변수에 할당하려고 시도했습니다. 먼저 변수에 할당하면 어떻게든 출력 이름을 바꿀 수 있을 것이라고 생각했습니다.

allthefiles= *.fasta

하지만 그것도 작동하지 않습니다. 이 질문을 뭐라고 불러야 할지 모르겠습니다. 이미 질문하셨다면 죄송합니다! 명령을 통해 여러 파일을 실행하고 각 입력에 대해 새로운 출력을 제공하는 방법은 무엇입니까?

답변1

for f in *.fasta; do 
    sh script.sh "$f" > "${f%.*}_output.fasta"; 
done

# ${f%.*} strips a shortest match of `.*` from the end of "$f"
# (= strips .fasta)

답변2

사용만들다!

이라는 파일을 작성합니다. GNUmakefile내용은 다음과 같은데 ↦ 문자를 넣은 곳에 탭 문자를 넣어줍니다(공백이 아닌 탭 문자여야 합니다).

all: $(filter-out %_output.fasta,$(wildcard *.fasta))

%_output.fasta: %.fasta
↦./script.sh $< >[email protected]
↦mv [email protected] $@

이제 모든 파일을 재생성하려면 .을 입력하십시오 make. 보너스로, 마지막 출력 파일이 생성된 이후 입력 파일이 변경되지 않은 경우 script.sh다시 실행되지 않습니다. 적극적으로 수정 script.sh하고 출력 파일을 다시 생성하려면 스크립트가 변경되면 파일도 다시 생성되도록 script.sh뒤에 추가하세요.%.fasta

설명하다:

  • 첫 번째 줄은 런타임 시 수행할 작업을 지정합니다 make all. 왜냐하면 이것이 첫 번째 줄이기 때문입니다(첫 번째 줄표적, makefile 용어로) make인수 없이 실행하면 동일한 작업이 수행됩니다.
  • 다음 섹션에서는 all:현재 디렉터리에 파일 이름 목록을 생성하고 .fasta이름이 _output.fasta.
  • 줄은 %_output.fasta: %.fasta다음으로 시작합니다.규칙_output.fasta( 로 시작하는 이름을 생성하는 방법을 설명합니다 .표적) 해당 .fasta파일(a의존).
  • 다음 탭으로 들여쓰기된 줄은 파일을 생성하기 위해 실행해야 하는 명령입니다.
  • 첫 번째 줄은 첫 번째 종속성( )을 파일 $<로 변환합니다..tmp
  • 두 번째 줄은 .tmp파일 이름을 대상 파일( $@)로 바꿉니다. 이 2단계 프로세스를 수행하는 이유는 어떤 이유로든 빌드가 중단되더라도 유효하지 않은 개체 파일이 남지 않기 때문입니다.

참고: Linux를 사용하고 있다고 가정합니다. 그렇지 않은 경우 make위의 코드를 사용하려면 시스템의 기본 명령 대신 GNU make를 설치하고 실행해야 할 수도 있습니다.

출력 파일에 다른 확장자를 사용하면 상황이 조금 더 쉬워집니다.

all: $(patsubst %.fasta,%.out,$(wildcard *.fasta))

.SUFFIX: .out .fasta
.fast.out:
↦./script.sh $< >[email protected]
↦mv [email protected] $@

all: foo.out bar.out첫 번째 줄을 명시적 파일 목록( ) 으로 바꾸면 Makefile해당 파일을 호출하여 make.

답변3

gnu 병렬을 사용하여 병렬로 실행할 수 있습니다.

parallel "sh script.sh {} > {}.out" ::: *

답변4

이것은 한 줄 솔루션입니다

find ./ -name "*.fasta" -exec sh -c 'script.sh ${0} > ${0}.log' {} \;

즉, 원하는 파일을 찾아 해당 파일에 대해 스크립트를 실행합니다. 사용 목적은 sh -c리디렉션 문자를 직접 해석하는 것이 아닙니다.>

관련 정보