次のディレクトリ構造があります。
Project/
|
+--Part1/
| |
| +--audio.mp3
|
+--Part2/
| |
| +--audio.mp3
|
+--Part3/
| |
| +--audio.mp3
...
Part1.mp3、Part2.mp3などのファイルにしたいです。
各フォルダには1つのファイルしか含まれていないため、ファイルが破損したり、同じ名前の複数のファイルを処理したりする危険はありません。
find
一種の/xargs
コマンドプラスとを使用してcut
これを行うことができるようですが、mv
実際にコマンドを設定する方法がわかりません。
答え1
これらの例はすべてのPOSIXシェルで実行でき、外部プログラムは必要ありません。
これにより、Part * .mp3ファイルがプロジェクトディレクトリと同じレベルに保存されます。
(cd Project && for i in Part*/audio.mp3; do echo mv "$i" ../"${i%/*}".mp3; done)
これにより、プロジェクトディレクトリにPart * .mp3ファイルが残ります。
for i in Project/Part*/audio.mp3; do echo mv "$i" ./"${i%/*}".mp3; done
これらのソリューションはシェルを使用してpattern matching
parameter expansion
新しいファイル名を生成します。
${parameter%word} Remove Smallest Suffix Pattern. The word is expanded to produce a pattern. The parameter expansion then results in parameter, with the smallest portion of the suffix matched by the pattern deleted.
答え2
rename
Perl(時々呼び出される)がある場合は、prename
次のことができます。
( cd Project && rename 's!(.+)/(.+)(\.mp3)!$1.$3!' */audio.mp3 )
これは、シェルグローブと一致するすべてのファイル名を取得し、*/audio.mp3
それをディレクトリ、ファイル名、および拡張コンポーネントに分割します。次に、ファイル名の部分を破棄し、ファイル名を変更します。
rename -n ...
何が起こるのかを確認するために使用するか、実行時に何が起こるのかを確認するため-v
に代わりに使用します。-n
答え3
pax -rwls'|.*/\(.*\)/audio\(\.mp3\)$|\1\2|p' \
-s'|.*||' /path/to/Project .
これは、POSIXコマンドラインアーカイブユーティリティを使用して、ツリーで見つかった各ルートディレクトリの名前付きpax
現在のディレクトリにハードリンクを作成します。parent_dirs_base.mp3
audio.mp3
/path/to/Project
。これにより、stderrのファイル名の変更がすべて印刷されます。
-k
リンク先と同じ名前の既存のファイルを潜在的に上書きするのを防ぐため、またはより良い方法で実行する前に最初に空のディレクトリに変更するのを防ぐために使用されます。
mv
私の考えでは、使用したいファイルを直接リンクするのではなく、最初にハードリンクを作成することに大きな利点があります。つまり、期待する結果が得られる結果と同じであることを確認する機会があるということです。今後原稿を削除してください。確認後、次のことができます。
find /path/to/Project -name audio.mp3 -exec rm {} +
...ファイルリンクを整理して1つずつ減らしてください。
答え4
Perlの味を使ったBash
for file in `find . -type f -name "*.mp3"`;
do
dir=$(dirname $file);
bdir=$(basename $dir);
bname=$(basename $file);
new=$bdir.$bname;
newname=${new//\.\./};
newname_with_path=$dir/$newname
if [ "$file" != "$newname_with_path" ]
then
echo mv -u $file $newname_with_path ;
fi
done
# replace 2 dots with nothing
# bash 4.1.2 centos 6.4 no problem with or without bashslash
newname=${new//../};