入力は次のファイル名になります。
A-B-000001-C
A-B-000002-C
.....
.....
A-B-999999-C
すべてのファイルは連続している必要があります。不足している連続ファイル名を見つけたいです。これには別の6桁のシリアル番号を使用します。アッ そして使用grep正規表現を使用して、ディレクトリにファイルがあることを確認します。
`ls|grep "A-B-${sequencenumber}-.*"|wc -l`
ただし、シェルスクリプトは数値を10進数として扱わず、次のように数字を10進数として扱うように強制する10#$シリアル番号その後、ファイルを検索するために必要な先頭のゼロを削除します。
この問題を解決する方法はありますか?
答え1
一部のシェル(例:bash)は、算術式の前にゼロの数字を8進数として扱います。この問題を解決する 1 つの方法は、1000001 から 1999999 までの計算など、前にゼロ以外の数字が追加された数字に対してのみ操作を実行することです。前にゼロのある希望の数値を取得するには、文字列操作を使用して前の1を削除します。
n=1000001
while [ "$n" -le 1999999 ]; do
digits=${n#1}
set "A-B-$digits-."*
if [ -e "$1" ] || [ -L "$1" ]; then
echo "${digits}: $#"
fi
n=$((n+1))
done
この方法はすべてのPOSIXシェルに移植可能であり、計算用のサブプロセスを生成しないため、高速化することができます(ただし、100万回の繰り返しはとにかく遅く、シェルのパフォーマンスは最高ではありません)。
上記のスクリプトでは、一致するファイルを含めてls
計算するwc
複雑で遅いコマンドを使用する代わりに、シェル組み込み構成を使用します。set "A-B-$digits-."*
位置引数を一致するファイルのリストに設定すると、次の行は一致する数($#
)を印刷します。一致する項目が1つ以上あります(一致する項目がない場合、パターンは変更されずに保持されるため[ -e "$1" ]
false [ -e "A-B-$digits-.*" ]
)。
答え2
答え3
wc -l
ファイル名に改行文字が含まれている場合、使用すると正しい結果は生成されません。
bash
でzsh
支柱の拡張を使用できます。
for n in {000001..999999}; do
f=A-B-$n-C
[ -f "$f" ] || printf '%s missing\n' "$f"
done
ksh93
オプションで有効braceexpand
:
for n in {1..999999%06d}; do
: the code above
done
ksh
と では、zsh
次のことができます。
typeset -Z6 i=1
max=999999
while [ "$i" -le "$max" ]; do
f=A-B-$i-C
[ -f "$f" ] || printf '%s missing\n' "$f"
: "$((i+=1))"
done
POSIX的に:
min=1
max=999999
while [ "$min" -le "$max" ]; do
f=$(printf "A-B-%0${#max}d-C" "$min")
[ -f "$f" ] || printf '%s missing\n' "$f"
: "$((min+=1))"
done
答え4
awk
私のために働く:
set x=`echo $< | awk '{printf "%d",$1}' ` ; echo $x
033 # this is what I entered
33 # this prints out