답변:
을 사용하여 가정 한 것처럼 ./a.out
UNIX 유형 플랫폼을 사용하는 경우 다음이 수행 됩니다.
for number in 1 2 3 4 ; do \
./a.out $$number ; \
done
다음과 같이 테스트하십시오.
target:
for number in 1 2 3 4 ; do \
echo $$number ; \
done
생산 :
1
2
3
4
더 큰 범위의 경우 다음을 사용하십시오.
target:
number=1 ; while [[ $$number -le 10 ]] ; do \
echo $$number ; \
((number = number + 1)) ; \
done
이것은 1에서 10까지를 출력하며, while
주석에 표시된 것처럼 훨씬 더 넓은 범위에 대해 종료 조건을 10에서 1000으로 변경하십시오 .
따라서 중첩 루프를 수행 할 수 있습니다.
target:
num1=1 ; while [[ $$num1 -le 4 ]] ; do \
num2=1 ; while [[ $$num2 -le 3 ]] ; do \
echo $$num1 $$num2 ; \
((num2 = num2 + 1)) ; \
done ; \
((num1 = num1 + 1)) ; \
done
생산 :
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1
4 2
4 3
seq
당신이 쓸 수 있도록 일련의 숫자는, 대부분의 (모든?) 유닉스 시스템에 존재 생성 명령 for number in ``seq 1 1000``; do echo $$number; done
합니다 (서열 명령이 아닌 두 가지의 각 측면에 하나의 역 따옴표를 넣고,이를 제대로 포맷하는 방법을 모른다 stackoverflow의 구문 사용)
make
일반적으로 각 줄을 별도의 하위 셸 에서 실행하는 것으로 취급 하기 때문 입니다. 계속하지 않으면 for number in 1 2 3 4 ; do
루프의 나머지 부분없이 (예를 들어) 서브 쉘을 실행하려고합니다 . 그것으로, 그것은 효과적으로 while something ; do something ; done
완전한 진술인 형식의 한 줄이됩니다 . $$
질문은 여기에 대한 답변 : stackoverflow.com/questions/26564825/...을 , 겉으로 :-) 바로이 대답에서 추출한 코드
GNU make를 사용하고 있다면 시도해 볼 수 있습니다.
숫자 = 12 34 해: $ (for var, $ (NUMBERS),. / a.out $ (var);)
생성하고 실행할 것입니다
./a.out 1; ./a.out 2; 3 번; ./a.out 4;
./a.out 1
. ./a.out 2
상관없이 실행됩니다.
사용 메이크업 이럴에 대한 주요 이유는이다 -j
플래그. make -j5
한 번에 5 개의 셸 명령을 실행합니다. CPU가 4 개인 경우, makefile을 잘 테스트하면 좋습니다.
기본적으로 다음과 같은 내용을보고 싶습니다.
.PHONY: all
all: job1 job2 job3
.PHONY: job1
job1: ; ./a.out 1
.PHONY: job2
job2: ; ./a.out 2
.PHONY: job3
job3: ; ./a.out 3
이것은 -j
친절합니다 (좋은 징조). 보일러 플레이트를 찾을 수 있습니까? 우리는 쓸 수 있습니다 :
.PHONY: all job1 job2 job3
all: job1 job2 job3
job1 job2 job3: job%:
./a.out $*
같은 효과 (예, 이것은 지금까지로 이전 배합과 동일 제조업체가 우려하고, 조금 더 컴팩트).
명령 줄에 제한을 지정할 수있는 추가 매개 변수 ( make
좋은 산술 매크로가 없으므로 지루 하므로 여기서 속이고 사용합니다 $(shell ...)
)
LAST := 1000
NUMBERS := $(shell seq 1 ${LAST})
JOBS := $(addprefix job,${NUMBERS})
.PHONY: all ${JOBS}
all: ${JOBS} ; echo "$@ success"
${JOBS}: job%: ; ./a.out $*
당신은 이것을 실행 make -j5 LAST=550
에, LAST
1000 디폴트.
.PHONY: all
make라는 파일을 찾습니다.all
. 이러한 파일이 존재하면 make는 해당 파일의 마지막 변경 시간을 확인하며 makefile은 의도 한대로 작동하지 않습니다. .PHONY
선언은 메이크업 알려줍니다 all
상징적 인 목표입니다. 따라서 Make는 all
대상이 항상 오래된 것으로 간주합니다 . 완전한. 설명서를 참조하십시오.
%
규칙에서 일치하는 $*
것이 레시피에서와 같이 사용할 수 있는 편의를 위해 하나를 사용 합니다.
나는 질문이 몇 살이라는 것을 알고 있지만,이 게시물은 위와 다른 접근법을 보여 주므로 누군가에게 유용 할 수 있으며 쉘 작업이나 개발자가 하드 코드 된 코드를 작성해야 할 필요성에 의존하지 않습니다 숫자 값의 문자열.
$ (eval ....) 내장 매크로는 친구입니다. 아니면 적어도 될 수 있습니다.
define ITERATE
$(eval ITERATE_COUNT :=)\
$(if $(filter ${1},0),,\
$(call ITERATE_DO,${1},${2})\
)
endef
define ITERATE_DO
$(if $(word ${1}, ${ITERATE_COUNT}),,\
$(eval ITERATE_COUNT+=.)\
$(info ${2} $(words ${ITERATE_COUNT}))\
$(call ITERATE_DO,${1},${2})\
)
endef
default:
$(call ITERATE,5,somecmd)
$(call ITERATE,0,nocmd)
$(info $(call ITERATE,8,someothercmd)
간단한 예입니다. 큰 값의 경우 꽤 확장 할 수는 없지만 작동하지만 ITERATE_COUNT 문자열은 각 반복마다 2 문자 (공백 및 점) 씩 증가하므로 수천 자릿수에 도달하면 단어를 계산하는 데 점진적으로 더 오래 걸립니다. 작성된대로 중첩 반복을 처리하지 않습니다 (별도의 반복 함수와 카운터가 필요합니다). 이것은 순수하게 gnu make이며 쉘 요구 사항은 아닙니다 (물론 OP는 매번 프로그램을 실행하려고했습니다. 여기서는 메시지를 표시하고 있습니다). $ (word ...)는 그렇지 않으면 오류가 발생하기 때문에 ITERATE 내의 if는 값 0을 포착하기위한 것입니다.
$ (words ...) 내장은 아라비아 숫자를 제공 할 수 있기 때문에 카운터로 사용할 문자열이 증가한다는 점에 유의하십시오. 쉘에서 무언가를 호출하여 그것을 달성하거나 동등하게 복잡한 매크로 작업을 사용하지 않는 한). 이것은 INCREMENTAL 카운터에 효과적이지만 DECREMENT 카운터에는 적합하지 않습니다.
나는 이것을 직접 사용하지 않지만 최근에는 라이브러리를 포함 할 때 다른 라이브러리를 가져올 때 알아야 할 다중 이진 다중 라이브러리 빌드 환경에서 라이브러리 종속성을 평가하기 위해 재귀 함수를 작성해야했습니다. 자체에는 다른 종속성 (일부는 빌드 매개 변수에 따라 다름)이 있으며 위와 비슷한 $ (eval) 및 카운터 방법을 사용합니다 (제 경우에는 카운터가 어떻게 든 끝없이 가지 않도록합니다. 얼마나 많은 반복이 필요한지보고하는 진단으로도 사용됩니다.
OP의 Q에 중요하지는 않지만 다른 가치가있는 것 : $ (eval ...)은 순환 참조에 대한 make의 내부 혐오를 피하는 방법을 제공합니다. 이는 변수가 매크로 유형 ( =) 대 즉시 할당 (: =로 초기화) 자체 할당 내에서 변수를 사용하고 싶을 때가 있으며 $ (eval ...)을 사용하면 그렇게 할 수 있습니다. 여기서 고려해야 할 중요한 것은 eval을 실행할 때 변수가 해석되고 해석되는 부분이 더 이상 매크로로 처리되지 않는다는 것입니다. 당신이하고있는 일을 알고 있고 RHS에 변수를 사용하려고한다면, 이것은 일반적으로 어쨌든 일어나고 싶습니다.
SOMESTRING = foo
# will error. Comment out and re-run
SOMESTRING = pre-${SOMESTRING}
# works
$(eval SOMESTRING = pre${SOMESTRING}
default:
@echo ${SOMESTRING}
행복합니다.
플랫폼 간 지원을 위해 명령 구분 기호 (같은 줄에서 여러 명령을 실행하기 위해)를 구성 할 수있게하십시오.
예를 들어 Windows 플랫폼에서 MinGW를 사용하는 경우 명령 구분 기호는 &
다음과 같습니다.
NUMBERS = 1 2 3 4
CMDSEP = &
doit:
$(foreach number,$(NUMBERS),./a.out $(number) $(CMDSEP))
이렇게하면 연결된 명령이 한 줄로 실행됩니다.
./a.out 1 & ./a.out 2 & ./a.out 3 & ./a.out 4 &
다른 곳에서 언급했듯이 * nix 플랫폼 사용 CMDSEP = ;
.
이것은 실제로 질문에 대한 순수한 대답이 아니라 그러한 문제를 해결하는 지능적인 방법입니다.
복잡한 파일을 작성하는 대신 makefile과 같은 bash 스크립트에 제어를 위임하십시오.
foo : bar.cpp baz.h
bash script.sh
script.sh는 다음과 같습니다.
for number in 1 2 3 4
do
./a.out $number
done
eval echo \$${$(var)}
; \ echo $$ var1; \ ((NUM = NUM + 1)); \ done all : set_var here SSA_CORE0_MAINEXEC는 이미 설정된 환경 변수이므로 변수 var1을 사용하여 해당 값을 평가하거나 인쇄하고 싶습니다. 위와 같이 시도했지만 작동하지 않았습니다. 도와주세요.
bash
해당 기능을 사용할 수 있습니다. 루프는이를 설명 할 수있는 기능 중 하나입니다.
set -e
for 루프의 접두사로 사용할 수 있습니다 . 예:
all:
set -e; for a in 1 2 3; do /bin/false; echo $$a; done
make
종료 코드와 함께 즉시 종료 <> 0
됩니다.
있지만 GNUmake 테이블 툴킷 진정한 갖는 while
루프를 필요로하는 것은 반복적 인 목록 인 경우 (실행의 두 개 또는 세 개의 단계로 GNUmake 프로그래밍 수단은 무엇이든), 간단한 솔루션이있다 interval
. 그것의 재미를 위해, 우리는 숫자를 16 진수로 변환합니다.
include gmtt/gmtt.mk
# generate a list of 20 numbers, starting at 3 with an increment of 5
NUMBER_LIST := $(call interval,3,20,5)
# convert the numbers in hexadecimal (0x0 as first operand forces arithmetic result to hex) and strip '0x'
NUMBER_LIST_IN_HEX := $(foreach n,$(NUMBER_LIST),$(call lstrip,$(call add,0x0,$(n)),0x))
# finally create the filenames with a simple patsubst
FILE_LIST := $(patsubst %,./a%.out,$(NUMBER_LIST_IN_HEX))
$(info $(FILE_LIST))
산출:
./a3.out ./a8.out ./ad.out ./a12.out ./a17.out ./a1c.out ./a21.out ./a26.out ./a2b.out ./a30.out ./a35.out ./a3a.out ./a3f.out ./a44.out ./a49.out ./a4e.out ./a53.out ./a58.out ./a5d.out ./a62.out
#I have a bunch of files that follow the naming convention
#soxfile1 soxfile1.o soxfile1.sh soxfile1.ini soxfile1.txt soxfile1.err
#soxfile2 soxfile2.o soxfile2.sh soxfile2.ini soxfile2.txt soxfile2.err
#sox... .... ..... .... .... ....
#in the makefile, only select the soxfile1.. soxfile2... to install dir
#My GNU makefile solution follows:
tgt=/usr/local/bin/ #need to use sudo
tgt2=/backup/myapplication/ #regular backup
install:
for var in $$(ls -f sox* | grep -v '\.' ) ; \
do \
sudo cp -f $$var ${TGT} ; \
cp -f $$var ${TGT2} ; \
done
#The ls command selects all the soxfile* including the *.something
#The grep command rejects names with a dot in it, leaving
#My desired executable files in a list.