ファイル名の数を減らすために、複数のファイルの名前を変更しますか?

ファイル名の数を減らすために、複数のファイルの名前を変更しますか?

私のファイル名が正しく指定されていませんが、-1は同期されませんでした。問題は、何千もの名前を変更する必要があるということです。

  • DBGC180_805754
  • DBGC180_805755
  • DBGC180_805756

到着

  • DBGC180_805753
  • DBGC180_805754
  • DBGC180_805755

私はbashスクリプトまたはunixコマンドを使用することを好みます。

答え1

次のことができます。

# {smallestfilenum..largestfilenum}

for i in {805754..999999}; do 
   mv "DBGC180_$i" "DBGC180_$(($i-1))";
done

小さい番号(例:805754..805758)で試して、期待どおりに機能していることを確認してください。新しい名前のファイルがすでに存在する場合、そのファイルは上書きされますので注意してください。

答え2

  1. 名前を変更するファイルをサブディレクトリに移動します(名前を変更せずに)。
  2. サブディレクトリのファイル名を元のディレクトリに変更します。

ステップ1がなくても可能ですが、2つの理由でステップ1をお勧めします。

  • コマンドが中断されると、どのファイルの名前が変更され、どのファイルが変更されていないかが明らかになるため、中断した部分から続行できます。
  • 間違った順序で名前を変更したり、既存のファイルの1つを上書きしたりすることを心配する必要はありません。

テストされていないシェルの断片(縮小された数字の前にゼロが付いていないという事実に依存します):

mkdir to_decrement
for x in DBGC180_80575[4-9] DBGC180_8057[6-9]? DBGC180_805[8-9]?? DBGC180_80[6-9]??? DBGC180_8[1-9]???? DBGC180_9?????; do
  mv "$x" to_decrement/
done
cd to_decrement
for x in *; do
  number="${x##*_}"
  mv -i -- "$x" "../${x%_*}_$((number-1))"
done
cd ..
rmdir to_decrement

そして扱いにくいおかげで、これをより簡単にすることができます。番号範囲グローバル、それ組み込みmvこれにより、コマンドラインの長さ制限が発生するのを防ぎます。パターンベースのバッチ名変更機能。 zshから:

autoload -U zmv
zmodload -m -F zsh/files b:zf_\*
mkdir to_decrement
zf_mv DBGC180_<805754-> to_decrement/
zmv 'to_decrement/(*)_(*)' '${1}_$(($2-1))'
rmdir to_decrement

答え3

だから名前を、toなどDBGC180_805754に変えたいです。これが私が解決したい問題です。DBGC180_805753...55...54

まず、このスクリプトを現在の場所のどこかに置き、PATH名前をwaltinator

#!/bin/bash
#step through the parameters 
while [[ -n "$1" ]] ; do
    oldname="$1"
    # shift the arguments left
    shift;
    # strip off the fixed part of the old name
    oldnum=${oldname##DBGC180_}
    # decrement the number (this is what was wanted, right?)
    newnum=$(( $oldnum - 1 ))
    # build the new, improved filename
    newname="DBGC180_$newnum"
    if [[ -f "$newname" ]] ; then
        printf "Cannot rename $oldname to $newname, $newname exists.\n" >&2
        exit 1
    fi
    mv --no-clobber "$oldname" "$newname"
done
exit 0

次の手順では、スクリプトが存在していると$HOME/bin/waltinator仮定しますchmod +x $HOME/bin/waltinator

find . -type f -name 'BDGC180_[0-9][0-9][0-9][0-9][0-9][0-9]` -print | \
    sort | \
    xargs $HOME/bin/waltinator

名前はシェルglobパターン"の後に6桁の数字()に一致するfindファイルを(特定の順序なしで)探します。ソートされたリストが必要なので(以前に名前を変更すると失敗します)、throughの出力を実行します。リストを減らす必要がある場合は、(ソートされた)ファイル名のリストを取得し、(ソートされた)ファイル名のリストを読み取りに渡すコマンドを作成します。BDGC180_[0-9]...97...96...96findsortxargs$HOME/bin/waltinatorman xargs

これを行うには、次の内容をお読みください。

for page in bash mv find sort xargs ; do
    man "$page"
done   

答え4

rename各数字を1を引いた数字に置き換えるために使用されます。

$ rename -v 's/\d{6}/sprintf("%06",($&-1))/e'    

ノート

  • renamePerl式を使用してファイルの名前を変更します。
  • srename正規表現パターンの一部または全部と一致するファイル名を変更することを指定します。
  • Perl 置換式の構造は次のとおりです。
    • s/PATTERN/REPLACEMENT/MODIFIER
  • \d{6}rename検索して置き換えるパターンです。小数点は6桁です。
  • $一致する部分文字列を格納する変数です\d{6}(この場合、「substring」はintです).
  • sprintf("%06",($&-1))に格納されている値を検索して$減少させ、その値を代替値として返します。先行ゼロを処理するために使用されます%06
  • erename代替項目がPerlステートメントとして評価され、対応する戻り値が代替テキストとして使用されることを指定します。
  • -vrenameechoに何をしてもらうようにします。

より安全にするには、このフラグを使用して何をすべきかを通知し、実行しないようにしてください-nrename

これは減少のみに機能するように見えるので、注意して処理してください。

関連情報