ファイル名の数をテキストファイルの対応する文字列に変更し、複数のファイルの名前を変更します。

ファイル名の数をテキストファイルの対応する文字列に変更し、複数のファイルの名前を変更します。

名前を変更したいファイルがたくさんあります。各ファイル名には数字(xxx)が含まれていますFIXED_PART_xxx_UNIQUE_PART

また、各行に数字と文字列を含むテキストファイルがあります。

001 string001
002 string002
...
112 string112

各ファイルには項目がありますが、必ずしも各項目にファイルがあるわけではありません。その部分を解析し、ファイルの文字列に置き換えてxxx各ファイルの名前を変更したいと思います。

最良のアプローチは何ですか?

編集:実際のファイル名は次のとおりです。

Berlin_Ost_034_some_variable_text.jpg

したがって、この場合、固定部分には下線が含まれていますが、すべてのフォルダに対して同じです。 xxx 部分は数字のみで構成されます。

出力はファイルの

Berlin_Ost_Sommer_some_variable_text.jpg

200個のファイルについて話しています。

テキストファイルには034 Sommerという1行が含まれています。

これがファイルの034部分がSommerに置き換えられた理由です。

ファイルにはさまざまな文字列が含まれていますが、文字、数字、ドイツ語の発音区別記号のみが含まれています。最初の部分は常に数値です。これは私が使用しているファイルの1つの一部です。

033 Winter
034 Sommer
035 Herbst
036 Frühling
037 Abends.kurz.vor.Sonnenaufgang

私はLinuxを使用しています。

答え1

zsh文字列にスペースやタブがないとします。

autoload -Uz zmv
typeset -A mapping=($(<mapping.txt))
zmv -n '(*_)([0-9](#c3))(_*.jpg)' '$1${mapping[$2]-$2}$3'

満足すれば削除-n(テスト実行)します。

複数の下線の間に一連の3桁の数字を含むファイル名の場合、一番右の数字が置き換えられます。これを使用すると、${mapping[$2]-$2}地図上の数値シーケンスが見つからない場合は変更されません。

すべてのファイルの接頭辞が同じ場合は、次のこともできます。

zmv -n '(Berlin_Ost_)([0-9](#c3))(_*.jpg)' '$1${mapping[$2]-$2}$3'

文字列にスペースまたはスペース(最初または末尾を除く)を含めることができる場合は、次のように連想配列を作成できます。

typeset -A mapping
while read -r key value; do mapping[$key]=$value; done < mapping.txt

代わりに。

ファイル名の3桁の数字をすべて変更するには、次のようにします。

zmv -n '*.jpg' '${f//(#m)[0-9](#c3)/${mapping[$MATCH]-$MATCH}'

この場合、両側でアンダースコアは見つかりません。私たちはできます:

zmv -n '*.jpg' '${f//(#b)_([0-9](#c3))_/${mapping[$match[1]]-$match[1]}'

しかし、これは001andを置き換えますが、2番目002は最初のゲームに含まれており、後のゲームの一部になることができないためfoo_001_bar_002_baz.jpg表示されません。foo_001_002_bar.jpg_

答え2

文字列リストの各項目を繰り返して、一致するファイルの名前を変更できます。 1行に圧縮することもできますが、コメントを追加できるようにここに残してください。

while IFS=' ' read -r key value                            # Extract the key and value
do
    for file in *_"$key"_*                                 # Loop across all matches
    do
        [ -f "$file" ] &&
            mv -- "$file" "${file/_${key}_/_${value}_}"    # Replace key with value
    done
done <keysandvalues                                        # Read the file of matches

代替式はキーの最初の項目のみを置き換え、両側を下線で区切る必要があります。キーまたは値はすべて含めることはできません/

代替ファイルの反復の副作用は、ファイル名に2つの代替文字列(たとえばBerlin_033_other_035_text.jpg)が含まれている場合、2つの代替文字列が一致したときに置き換えられることです(結果はですBerlin_Winter_other_Herbst_text.jpg)。問題がある場合は、名前を変更したファイルを別のディレクトリに移動すると問題が解決する可能性があります。

答え3

_some_variable_text数値が含まれていないと仮定する解決策は次のとおりです。

$ for i in *.jpg; do
    s="$(grep "${i//[^0-9]/}" file.txt)"
    echo mv -- "$i" "${i//[0-9]*/}${s//* /}_${i//*[0-9]_/}"
    # to actually perform the command remove the echo
    # do a backup first
  done
mv -- Berlin_Ost_034_some_variable_text.jpg Berlin_Ost_Sommer_some_variable_text.jpg

  • ファイルを繰り返します。
  • s="$(grep "${i//[^0-9]/}" file.txt)"キー抽出
  • mv -- "$i" "${i//[0-9]*/}${s//* /}_${i//*[0-9]_/}"ファイル名の他の部分を取得するには、パラメータ置換を使用してファイル名を変更します。

答え4

一行

prefix="foo" ls | grep -oP "(?<=${prefix}_).*" | xargs -I % sh -c 'mv ${prefix}_% ${prefix}_$( echo % | cut -d"_" -f1 | grep -f - filenames.txt | cut -d" " -f2 )_$( echo % | cut -d"_" -f2- ) '

fooプレフィックス(FIXED_PART)とファイル名はfilenames.txtどこにありますか?

説明する:

現在のディレクトリで始まるすべてのファイル名を取得しますが、prefixプレフィックスの後の部分のみが一致しますgrep -oP "(?<=${prefix}_).*"。各行(1)に対して、ファイル名を+から++にprefix変更します。(1)prefix(search in the file for the first part of (1), and get the corresponding string)remaining part of (1)

見る

関連情報