다른 인수로 프로그램을 시작하는 스크립트를 작성해야하지만 Bash를 처음 사용합니다. 다음과 같이 프로그램을 시작합니다.
./MyProgram.exe Data/data1.txt [Logs/data1_Log.txt]
.
내가하고 싶은 것에 대한 의사 코드는 다음과 같습니다.
for each filename in /Data do
for int i = 0, i = 3, i++
./MyProgram.exe Data/filename.txt Logs/filename_Log{i}.txt
end for
end for
그래서 첫 번째 인수에서 두 번째 인수를 만드는 방법에 대해 의아해합니다. 그래서 dataABCD_Log1.txt처럼 보이고 프로그램을 시작합니다.
답변
먼저 몇 가지 참고 사항 : Data/data1.txt
인수로 사용할 때 실제로 /Data/data1.txt
슬래시가 있어야 합니까? 또한 외부 루프는 .txt 파일 또는 / Data의 모든 파일 만 검색해야합니까? 다음은 /Data/data1.txt
.txt 파일 만 가정 하고 이에 대한 답변입니다 .
#!/bin/bash
for filename in /Data/*.txt; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt"
done
done
노트:
/Data/*.txt
(/ 데이터의 텍스트 파일의 경로로 확장 포함 은 / 데이터 / 부분)$( ... )
쉘 명령을 실행하고 해당 지점에서 출력을 명령 행에 삽입합니다.basename somepath .txt
.txt를 끝에서 제거하여 somepath의 기본 부분을 출력합니다 (예 :/Data/file.txt
->file
)
당신이 MyProgram을 실행하는 데 필요한 경우 Data/file.txt
대신 /Data/file.txt
, 사용은 "${filename#/}"
선도적 인 슬래시를 제거합니다. 반면에 실제로 스캔 Data
하지 /Data
않으려면을 사용하십시오 for filename in Data/*.txt
.
답변
스레드를 괴롭히는 것은 유감 스럽지만, globbing하여 파일을 반복 할 때마다 glob가 일치하지 않는 코너 케이스를 피하는 것이 좋습니다 (루프 변수가 (일치하지 않는) glob 패턴 문자열 자체로 확장됩니다).
예를 들면 다음과 같습니다.
for filename in Data/*.txt; do
[ -e "$filename" ] || continue
# ... rest of the loop body
done
참조 : 배쉬 함정
답변
for file in Data/*.txt
do
for ((i = 0; i < 3; i++))
do
name=${file##*/}
base=${name%.txt}
./MyProgram.exe "$file" Logs/"${base}_Log$i.txt"
done
done
name=${file##*/}
대체 ( 쉘 매개 변수 확장은 ) 마지막까지 선두 경로 이름을 제거합니다 /
.
base=${name%.txt}
대체 후행를 제거합니다 .txt
. 확장 기능이 다를 수 있다면 조금 까다 롭습니다.
답변
디렉토리 구조를 안전하게 반복하기 위해 read와 함께 null로 구분 된 출력 옵션을 사용할 수 있습니다.
#!/bin/bash
find . -type f -print0 | while IFS= read -r -d $'\0' file;
do echo "$file" ;
done
그래서 당신의 경우를 위해
#!/bin/bash
find . -maxdepth 1 -type f -print0 | while IFS= read -r -d $'\0' file; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$file" 'Logs/'"`basename "$file"`""$i"'.txt'
done
done
추가적으로
#!/bin/bash
while IFS= read -r -d $'\0' file; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$file" 'Logs/'"`basename "$file"`""$i"'.txt'
done
done < <(find . -maxdepth 1 -type f -print0)
스크립트 (process)의 현재 범위에서 while 루프를 실행하고 필요한 경우 find 출력을 변수 설정에 사용할 수 있습니다.
답변
Windows 파일 (.exe)을 실행하려는 것 같습니다. 확실히 powershell을 사용해야합니다. 어쨌든 리눅스 bash 쉘에서 간단한 one-liner로 충분합니다.
[/home/$] for filename in /Data/*.txt; do for i in {0..3}; do ./MyProgam.exe Data/filenameLogs/$filename_log$i.txt; done done
또는 bash에서
#!/bin/bash
for filename in /Data/*.txt;
do
for i in {0..3};
do ./MyProgam.exe Data/filename.txt Logs/$filename_log$i.txt;
done
done