通常、特定のタスク用のシェルスクリプトを作成するときに、次のファイルのリストを作成します。
#/bin/sh
read -d '' imagefiles <<EOF
./01/IMG0000.jpg
./01/IMG0001.jpg
./01/IMG0002.jpg
./01/IMG0003.jpg
./01/IMG0004.jpg
./01/IMG0005.jpg
./01/IMG0006.jpg
./01/IMG0007.jpg
(a whole bunch of files down to ./10/IMG0102.jpg)
EOF
for i in $imagefiles
for j in range(len(commands))
do
mv $i ./$j.jpg
done
done
この場合、出力を繰り返すことができるようにしたいのですが、Gillesが提案したように、seq
この部分をPythonで書いてください(例えば、各コマンドがj回実行されて約100,000回実行されることを知っています)。以前は736個のファイルを順番に名前を変更しましたが、今では名前を変更するファイルが1000個を超えています。これを行うより良い方法があると確信していますが(躊躇しないでください)、コマンドリストと他の繰り返し可能な項目を繰り返す方法を知ることもできます。
答え1
いいですね。 2つの反復可能項目を圧縮しようとしています。つまり、追加のカウンタを使用して複数の文字列を繰り返すループが必要です。カウンターを実装するのはとても簡単です。
n=0
for x in $commands; do
mv -- "$x" "$n.jpg"
n=$(($n+1))
done
これは、繰り返したい要素にスペース(またはワイルドカード)が含まれていない場合にのみ機能します。項目が改行で区切られている場合は、ワイルドカードをオフにして改行に分割します。
n=0
IFS='
'; set -f
for x in $commands; do
mv -- "$x" "$n.jpg"
n=$(($n+1))
done
set +f; unset IFS
データを一度だけ繰り返す必要がある場合は、ループを実行してくださいread
(参照:while IFS= read
代わりに、なぜそれほど頻繁に使用されますかIFS=; while read..
?詳細な説明は)
n=0
while IFS= read -r x; do
mv -- "$x" "$n.jpg"
n=$(($n+1))
done <<EOF
…
EOF
配列(bash、ksh、またはzsh)を持つシェルを使用している場合は、配列に要素を保存します。 zshでsetopt ksh_arrays
0から始まる番号付き配列要素を実行するか、1から始まる配列要素番号付けを開始するようにコードを調整します。
commands=(
./01/IMG0000.jpg
…
)
n=0
while [[ $n -lt ${#commands} ]]; do
mv -- "${commands[$n]}" "$n.jpg"
done
答え2
シェルがある場合、bash
このプログラムを実行する必要はありませんseq
。ただ使用
for i in {1..736}
do
前にゼロのあるシーケンスが必要な場合は{001..736}
(even {0001..0736}
)のみを使用してください。
また、可能であればバックティック(これがどのように物事を混乱させるかについては、この質問を参照してください。)。
もう1つのことは、ファイルグループを操作したい場合にこの機能が役に立つ可能性があることです。
for file in /some/path/*
do
すべてのファイルで動作します(およびフォルダ)ディレクトリに/some/path/
。範囲をファイルに絞り込むには、次のような[ -f "$file" ]
同様のテストを使用できます。
for file in /some/path/*
do
[ -f "$file" ] || continue
(do your stuff here)
また、設定/some/path/*
はのようなシェルモードで調整できます。/some/path[123]/*
/some/path[A-Z]/b*[e-g]*
/some/path{1,5,23}/*
質問の最初の部分については、次のようにネストされたfor
(または任意の)ループを使用できます。while
for cm in $commands; do
for file in /some/path[ab]{1,4,2}/*.log; do
mv "${file}" "${file//text/replacement}"
done
done
答え3
Bashでは、複数の操作を並列に繰り返すことはできないと思います。
始めましょうi=1
。その後、ファイルのリストが繰り返され、let i=$i+1
ループに含まれます。$i -ge 736
また、ループカウント後に入力された項目の繰り返しを停止したい場合は、ループを停止するテストも含まれます。
i=0
for file in ./{01..10}/*jpg; do
let i=$i+1
mv "$file" "$i-$file"
done
Xファイルを閉じようとすると、次のテストを使用できます。
[[ $i -ge 736 ]] && return || let i=$i+1
答え4
Bashは配列をサポートしています:
http://tldp.org/LDP/abs/html/arrays.html
または
COUNT=0
for i in `ls *.txt`
do
COUNT=`expr $COUNT + 1`
mv "$i" "$COUNT-$i"
done
これにより、a.txt b.txt c.txt ファイルの名前が 1-a.txt 2-b.txt 3-c.txt に変更されます。