私は自分のプログラムを異なる引数で起動するスクリプトを書く必要がありますが、私は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 if
end for
だから私は本当に最初のものから2番目の引数を作成する方法に困惑しているので、それはdataABCD_Log1.txtのように見えて私のプログラムを開始します。手助けは大歓迎です。
P.S似たような質問があることは知っていますが、ログファイル名の作成には何も見つかりませんでした。
最初にいくつか注意してください。引数として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
は/ Data内のテキストファイルのパスに展開されます(含む the/Data /部分)$( ... )
はシェルコマンドを実行し、その出力をコマンドラインのその位置に挿入します。basename somepath .txt
はsomepathのベース部分を、末尾から.txtを削除して出力します(例:/Data/file.txt
- > file
)MyProgramをData/file.txt
ではなく/Data/file.txt
で実行する必要がある場合は、"${filename#/}"
を使用して先頭のスラッシュを削除します。一方、スキャンしたいのが実際には/Data
ではなくData
である場合は、for filename in Data/*.txt
を使用するだけです。
スレッドをネクロミスして申し訳ありませんが、globを使用してファイルを反復処理するときは、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を使用してfinds 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)
スクリプト(プロセス)の現在のスコープでwhileループを実行し、必要に応じて変数の設定にfindの出力を使用できるようにします。