サイズに基づいてファイル名を変更する Bash スクリプト

サイズに基づいてファイル名を変更する Bash スクリプト

コマンドプロンプトからの入力に従ってフォルダー内のファイルの名前を変更する bash スクリプトがあります。

echo "Please rename and press enter" read rename 

if [ -z "$rename" ]; then 
  printf "no caption was selected, aborting!\n"
  exit 1
fi 

printf "rename is $rename\n" count=1

for i in *.jpg; do 
  j=printf "%04d" $count
  j="$rename"$j".jpg"
  count=$((count + 1))
  mv "$i" $j
done  
fi 
shift 
done

フォルダー内のファイルのサイズに応じて名前が変更されるように、このスクリプトを変更するにはどうすればよいですか?

ファイルをサイズ順に並べ替えると、フォルダー内では次のようになります。

a009      978kb
a001      567kb
a003      499kb
a008      432kb

したがって、結果のファイルの名前を変更したいと思います。

a001      978kb
a002      567kb
a003      499kb
a004      432kb

答え1

このようなもの:

echo "Please rename and press enter"
read rename 

ls |
  # prepend filename with file size in bytes
  parallel stat -c %s,,sep,,%n --  |
  # sort by number
  sort -n |
  # rename to sequencenumber followed by size in bytes
  parallel -q --colsep ,,sep,, mv {2} "$rename"{#}_{1}

答え2

主なトリックは、

    for i in *.jpg

    for i in $(ls -S *.jpg)

しかし、Kusalananda が指摘したように、これは「適切な」ファイル名 (スペースや制御文字なし) を前提としているため、別のアプローチがあります。

count=1
ls -S --escape *.jpg | while read f; do
    n=$(printf "%04d" $count)
    ((count++))
    mv --no-clobber "$f" "$rename$n.jpg"
done

-Sファイルサイズを小さくして並べ替え、
--escape改行が埋め込まれた名前による損傷を防ぎ、
--no-clobberスクリプトが2回実行された場合に宛先ファイルが上書きされるのを防ぎます。

PS Ole Tange の回答は、同じことを実行する非常に優れた効率的な方法ですが、何千ものファイルを定期的に名前変更しない限り、違いはわからないでしょう。

答え3

シェル内zsh:

typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
    count=$(( count + 1 ))
    mv -i -- "$name" "a$count.jpg"
done

これは、現在のディレクトリにあるファイル名のサフィックスを持つすべての通常ファイルを.jpg、最大から最小の順に反復処理します。各ファイルの名前を に変更します。ここには、これまでに処理されたファイルのゼロで埋められた整数の数がaNNN.jpg表示されます。NNN

glob修飾子は、 (「長さによる逆順」)(.DNOL)を使用して一致するファイル名を正しい順序に並べ、 (「通常のファイルとドッ​​ト ファイル」)を使用して通常のファイル (隠し名前を含む) のみを選択します。一致する名前がない場合 (「null glob」)、パターンは何も展開されません。OL.DN

これは、インストールされているすべての Unix システム上の有効なファイル名すべてで機能しますzsh

これを使用するにはbash:

zsh -c 'typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
    count=$(( count + 1 ))
    mv -i -- "$name" "a$count.jpg"
done'

$rename次のように使用する代わりに、ファイル名のプレフィックスとして渡したい変数がある場合a:

zsh -c 'typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
    count=$(( count + 1 ))
    mv -i -- "$name" "$1$count.jpg"
done' zsh "$rename"

zsh最後の行の はタイプミスではなく、 の値がスクリプト内で$renameとして使用されていることに注意してください。$1zsh -c

関連情報