다음과 같이 폴더의 모든 파일에 대해 스크립트를 실행하고 싶습니다.
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
리디렉션 문자를 직접 해석하는 것이 아닙니다.>