名前を変更したいファイルがたくさんあります。各ファイル名には数字(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]}'
しかし、これは001
andを置き換えますが、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)
見る