複数のフォルダがあります。
1
2
3
4
5
したがって、各フォルダには次のファイルがあります。
00123.mp3
00133.mp3
00150.mp3
だからすべてを削除したいです。0ファイル名の先頭にある場合
私はこれを試しました
for file in *; do echo mv "$file" "${file//[ ()@0]/}"; done
しかし、それはすべて削除0先頭とファイル名の内部(最初に必要)は、サブディレクトリでも機能しません。
答え1
Bashを使用している場合、このスクリプトは要求された操作を実行します。
#!/bin/bash
shopt -s extglob
while IFS= read -d '' f ; do
file=${f##*/}
dir="${f%/*}/"
echo \
mv "$dir$file" "$dir${file##+(0)}"
done < <(find . -type f -name '0*.mp3' -print0)
移動するファイルのリストに同意すると、その行をecho \
コメントアウトして実際にコマンドを実行します。mv
または移植性のための次のshバージョン:
#!/bin/sh
find . -type f -name '0*.mp3' -print |
while IFS= read f; do
file=${f##*/}
dir="${f%/*}/"
f2=$file; until [ "$f2" = "${f2#0}" ]; do f2=${f2#0}; done
echo \
mv "$f" "$dir${f2}"
done
答え2
rename
あなたの質問にLinuxタグが付けられているので、またはコマンドを使用することができますprename
(prename
もう使用されていませんが、まだ動作します)。どちらの場合も、パターンベースの名前を変更するためのPerlスクリプトです。
グループマッチングを実行し、globを使用してファイルのみを*.mp3
渡すと、次のことができます。.mp3
$ prename -nv 's/(^0*)(.*).mp3/$2.mp3/' *.mp3
Deprecated program in use: rename as shipped with the Debian perl package will be removed after the release of stretch. Please install the separate 'rename' package which will provide the same command.
000004500.mp3 renamed as 4500.mp3
00123.mp3 renamed as 123.mp3
00133.mp3 renamed as 133.mp3
00150.mp3 renamed as 150.mp3
-n
とはテストの-v
実行と詳細なテストにのみ使用されます。-n
実際の名前変更を適用するには、削除してください。
rename
vsについて混乱している場合は、次prename
をお読みください。対応する回答これにより混乱がなくなります。しかし……気にしないことをお勧めします。複雑すぎる :) 要点は、ksh
シェルを使用しない限り、どちらの場合も示されているとおりに機能することです。
サブフォルダのファイル名を変更する再帰的な方法は via ですがfind
、提供されているようにファイルパスの前のエントリを処理するには、置換パターンを含むいくつかの曲芸が必要ですfind
。
find ./testdir/ -type f -name "*.mp3" -exec prename -nv 's/(.*)(\/0*)(.*).mp3/$1\/$3.mp3/' {} \;
上記のコマンドは、テストケースで次のように実行されます。
$ find ./testdir/ -type f -name "*.mp3" -exec prename -nv 's/(.*)(\/0*)(.*).mp3/$1\/$3.mp3/' {} \; 2>/dev/null
./testdir/000004500.mp3 renamed as ./testdir/4500.mp3
./testdir/00150.mp3 renamed as ./testdir/150.mp3
./testdir/00133.mp3 renamed as ./testdir/133.mp3
./testdir/00123.mp3 renamed as ./testdir/123.mp3
\d
数値カテゴリを指定すると、若干の改善がある可能性があります。
find ./testdir/ -type f -name "*.mp3" -exec prename -nv 's/\/0*(\d*\.mp3)/\/$1/' {} \;
Stéphane Chazelasは、コメントで/0/1.mp3
誤って名前が変更される可能性について言及しました.//1.mp3
。私はいくつかのテストケースを受け取り、結果を得ました./testdir/0/000987.mp3 renamed as ./testdir/0/987.mp3
。欲張りなマッチングが効果があると./testdir/007/00123.mp3 renamed as ./testdir/007/123.mp3
思います。0*
彼はまた、[^/]
コメントにファイル名パターンマッチングを追加することを提案しました。 Unixファイル名にはバックスラッシュを使用できませんが、個々のファイルには使用できないため、これは良い考えです。しかし、これをよりよく実装する方法がわかりませんが、ファイル名の一致0.mp3
や000.mp3
タイプの提案もまだありません。
答え3
そしてzsh
:
autoload zmv # best in ~/.zshrc
zmv -n '0#(*.mp3)' '$1'
(満足したら削除してください-n
(模擬実行))。
#
in のグローバル演算子はzsh
正規*
表現演算子に似ています。
0000.mp3
名前がに変わります.mp3
。これを防ぐには、次のように変更できます。
zmv -n '0#([0-9]*.mp3)' '$1'
再帰的に:
zmv -n '(**/)0#([0-9]*.mp3)' '$1$2'
例で提案されているように文字を削除するには、() @
次のことが必要になる場合があります。
zmv -n '(**/)0#([0-9]*.mp3)' '$1${2//[() @]}'
(ただし、ファイル名で数字で始まらない文字は削除されません。)