find . -type f -name '*authors-name-string*' -exec bash -c 'mv "$0" "${0/authors-name-string/}"' {} \;
ファイル名にランダムに含まれる作成者名のテキスト文字列を含む複数レベルのディレクトリにネストされたファイルの名前を変更しようとしています。作成者名で始まり、残りの元のファイル名が続く新しいファイル名を作成します。ただし、元のファイル名の任意の場所に作成者名文字列はありません。
上記のシェルコマンドラインはファイル名からAuthors-name-text文字列を再帰的に削除しますが、まだ何をすべきかを見つけることができませんでした。次に、Authors-name-text(および末尾の「_」下線)をTheに追加します。ファイル名の先頭。デフォルトでは、作成者名テキストをファイル名の現在の場所からファイル名の先頭(下線付き)に移動したいと思います。私が知る限り、私のSynology NASで呼び出されるbashのバージョンはv4.3です。 MacBookでSSH経由でログインしました。
簡単なディレクトリのリストを表示すると、同じ作成者によって作成されたディレクトリ内のいくつかのファイルが一緒にグループ化されて表示されるように、トピックディレクトリ名で構成されたさまざまなディレクトリにある数千のファイルをインポートしようとします。
find . -type f -name '*authors-name-string*' -exec bash -c 'mv "$0" "authors-name-string_${0/authors-name-string/}"' {} \;
フルファイル名パスの前に「authors-name-string_」を挿入しようとすると、上記のコマンドラインは失敗します。ただし、その名前の開始ディレクトリがないため、MVコマンドは文句を言いますが、必要に応じてファイル名の元の場所から作成者名文字列を削除します。
答え1
アッセイを拡張し、パラメータ拡張を活用してください。
export author_string='author1'
export new_string='author1'
find . -type f -name "*${author_string}*" \
-exec sh -c '
path="${1%/*}"
tmp="${1%%${author_string}[^/]*}"
before="${tmp##*/}"
after="${1##*${author_string}}"
echo mv -- "$1" "${path}/${new_string}_${before}${after}"' sh {} \;
あなたの質問を完全に理解していないので、私の前提は次のとおりです。
名前に固定文字列を含むファイルを検索していますauthor_string
。ここでは
、ディレクトリツリーのすべての場所でファイル名を変更しています。
ファイルの新しい名前は固定文字列で始まります(同じか異なるauthor_string
場合は大きな違いはありません)。ここでは変数ですnew_string
。ファイルの新しい名前の残りの部分は
古い名前と同じです。author_string
削除されます。
このコードでは:
呼び出しシェルで使用できるように古い/新しい文字列をエクスポートします
find
。移植性を念頭に置いて、コードスニペットに示すように
-exec
invocationを代わりに使用してくださいsh
。これは通常、シェル/コマンドの名前を設定するために使用されるためです。$1
$0
$0
各ファイルのフルパスを分割します。
path="${1%/*}"
ファイル名部分が削除されたフルパス。${parameter%word}
パターンに一致するサフィックスを削除しますword
。tmp="${1%%${author_string}[^/]*}"
各ファイルのフルパスの前の部分をキャプチャしますauthor_string
。${parameter%%word}
削除最長パターンに一致するサフィックスですword
。通常、[^/]
ディレクトリ名にこのような内容がある場合は無視します。author_string
before="${tmp##*/}"
ファイル名の部分文字列のみをキャプチャ:${parameter##word}
パターンに一致する最も長いプレフィックスを削除しますword
。after="${1##*${author_string}}"
ファイル名次の部分ですauthor_string
。
各ファイルの名前を変更します。
ファイル名で繰り返すと、author_string
2つの発生の間のすべての内容が失われます。
また、文字通り一致させるには、\
特別なパターン一致意味のある文字をエスケープ(使用)する必要があることに留意してください。author_string
ディレクトリツリーが与えられたら:
$ tree .
.
├── testdir
│ ├── title2_author1_date.book
│ ├── title3_author1_date.book
│ └── title4_author2_date.book
├── title1_author1_date.book
└── title5_author2_date.book
このコードの機能は次のとおりです。
$ export author_string='author1' new_string='author1'; find . -type f -name "*${author_string}*" -exec sh -c 'path="${1%/*}"; tmp="${1%%${author_string}[^/]*}"; before="${tmp##*/}"; after="${1##*${author_string}}"; echo mv -- "$1" "${path}/${new_string}_${before}${after}"' sh {} \;
mv -- ./title1_author1_date.book ./author1_title1__date.book
mv -- ./testdir/title3_author1_date.book ./testdir/author1_title3__date.book
mv -- ./testdir/title2_author1_date.book ./testdir/author1_title2__date.book
echo
実際にファイル名を変更する準備ができたと思われる場合は、コマンドからそのファイルを削除してください。
引用:
パラメータ拡張「The Open Group Base Spec Issue 7, 2018 Edition」(POSIX.1-2017)より
答え2
Larry Wallの職業のようですねrename
。同じ名前の別のコマンドがあることに注意してください。このコマンドは安心して書かれています。