負の名前のファイル名のパラメータ拡張エラー

負の名前のファイル名のパラメータ拡張エラー

私のディレクトリには次のファイルがあります。

$ ls *
-008.png  0052.png -002.jpg  0043.png  -005.png  0044.png ...

ファイルをサブディレクトリにコピーしsubdir(既存のファイルを上書きせずに)、ファイル名に指定された数字(10など)を追加してファイル名を変更したいと思います。

$ ls subdir/*
0002.png  0062.png 0008.jpg  0053.png  0005.png  0054.png ...

これは私のbashコマンドです

for filename in *
do
basename=${filename%.*}
extname=${filename#*.}
basename_new=$(printf %04d $((10#${basename}+10))); # 10#-008: value too great for base (error token is "003")
if [ ! -e subdir/"$basename_new".* ];  # [: subdir/.: binary operator expected
cp "$filename" "$basename_new"."$extname"
fi
done

ネガティブな名前を持ついくつかのファイルでは、forと同じエラーが発生します-008.png(しかしforではない-002.png、理由はわかりません)。

次に割り当てられた行の場合basename_new

10#-008: value too great for base (error token is "008")

次の行の場合if:

# [: subdir/.: binary operator expected

このエラーが何を意味するのか知りたいです。どうすれば解決できますか?

ありがとうございます。

答え1

ダッシュで始まる単語は通常オプションと見なされます。これにより、ls *コマンドは理解できない一連のオプションを受け取り、ls処理ls 001.png -002.png ...します。 、、...-002.pngなどの多くのコマンドでも同様です。cpmv

解決策1:ファイルの前にパスを付けます。すべての場合に有効です。

ls ./*

解決策#2:特にGNUの世界の多くのコマンドは、二重ダッシュを引数として受け入れ、次のものがオプションではないことを示しています。

ls -- *

ただし、先行ダッシュはループには影響しませんfor


「値が下数に比べて大きすぎる」というのは、-0080から始めて8進数として扱われるからです。ただし、8は有効な8進数ではありません。クイックフィックスは次のことですbc

printf -v basename_new %04d "$(bc <<< "${basename} + 10")"

問題はifnullが原因で発生basename_newし、上記の修正で消えます。

答え2

そしてzsh

$ autoload zmv
$ zmv -n '((-|)<->).(png|jpg)' '${(l:4::0:)$(($1 + 10))}.$3'
mv -- -002.jpg 0008.jpg
mv -- 0043.png 0053.png
mv -- 0044.png 0054.png
mv -- 0052.png 0062.png
mv -- -005.png 0005.png
mv -- -008.png 0002.png

-n実際に実行されたタスクを削除)

  • (-|)glob:-または "": オプション-
  • <->glob:一連の10進数(類似している<x-y>が境界はありません)。
  • ${(l:4::0:)param}:左パディング(および切り捨て)がゼロの長さ4です。
  • $(($1 + 10))(...):パターンでキャプチャされたデータの最初のペアで10ずつ増加します(zshゼロで始まる数字が8進数で処理されることに問題はありません。)このオプションを設定しても、通常のzshランタイムに戻るオプションにはoctalzeroes影響しません。zmv

答え3

10#-008-00810進数に変換されません。10#記号よりは数字の前に来なければならないからだと思います。

関連情報