web-dev-qa-db-ja.com

findコマンドを使用してファイル名から(1)を削除する方法

最近、Mac OS 10.7(Lion)でXLDを使用して、すべてのFLACファイルを44.1 kHzの低いサンプリングレートと24ビットのビット深度に変換しました(iPhone/iPodはそれ以上のものをサポートしていないため)。

以前のすべてのファイルを上書きするようにXLDに指示しましたが、XLDはfromのようにファイルの最後に_(1)_を追加しました

_some_song.m4a
_

_some_song(1).m4a
_

だから今私は変換したすべてのFLACファイルからその_(1)_を削除したいと思います。

おそらく何らかのプログラムやAppleScriptを使用してファイルの名前を変更できたはずですが、昔ながらのコマンドラインを使用して学習したかったのです。

find . -name *\(1\).m4aが変換されたすべてのFLACファイルを取得することを私は知っています。

次に、見つかったすべてのファイルの名前を変更するには、_-exec_とmvを使用して何かを行う必要があることがわかります。しかし、私が理解できないのは、元のファイル名を保持し、_(1)_のみを削除する方法です。

変更したくないファイル名の部分を保存するために、グループの正規表現をキャプチャする必要があるかもしれません。または、すべてを1行で実行することは不可能であり、シェルスクリプトを作成する必要があります(これはそれほど快適ではありませんが、試してみるつもりです)。

ヒントや提案は大歓迎です!ありがとう!

13
hobbes3

最後の手段を除いて、find出力を解析しようとしないでください。 Unixファイルシステムでは、ファイル名は文字列(一般的な誤解)ではなく、/以外の任意の文字を含むことができるバイナリブロブであることを理解することが重要です。とヌル文字。ファイル名を安全かつ正確に解析することは、99%の場合、それを完全に避けたいと思うほどの苦痛です( @ yarekの回答)のsed式がどれほど毛深いかを見てください であり、それでもすべてのケースを網羅しているわけではありません)。ありがたいことに、この場合、はるかに簡単なアプローチがあります。

find . -name '*(1).m4a' -execdir sh -c \
'for arg; do mv "$arg" "${arg%(1).m4a}".m4a; done' _ {} \+
13
jw013

DebianとUbuntuでは、rename 's/\(1\)//' *.m4aを使用して問題を解決できます。

6
Dom

Zshでは、 zmv を使用します。

autoload zmv      # you can put this line in your .zshrc
zmv '(*)\(1\)(*)' '$1$2'

2番目の引数(新しい名前)では、$1および$2括弧で囲まれたグループを参照してください(PATTERN)ソースパターンで。この名前の変更を書く別の方法は

zmv '(*)' '${1/\(1\)/}'

次のアプローチでは、生成されたコマンドをプレビュー/プルーニングする機能が提供されますbefore実行するだけで、非常に移植性が高くなります。Macだけでなく、bashだけでなく、GNU sed; find(1)コマンドのないシステムでも、問題なくdu(1)に置き換えることができます。

find . -name '*(1).m4a' |
sed 's/\(.*\)(1).m4a$/mv & \1.m4a/' 

印刷されたコマンドに満足したら、| sh -xを追加して再実行します。

ファイル名のスペースが気になる場合は、別のsを追加して、すべてのスペースをエスケープします。

find . -name '*(1).m4a' |
sed -e 's/ /\\ /g' -e 's/\(.*\)(1).m4a$/mv & \1.m4a/'

他の特別な文字が予想される場合は、少し注意が必要です。

find . -name '*(1).m4a' |
sed -e "s/'/'\\\\''/g" -e 's/\(.*\)(1).m4a$/mv '\''&'\'' '\''\1.m4a'\'/

最初の関数は、すべての'を、'...'-エスケープされた文字列の途中で文字通りに解釈されるような形式に変換します。 2番目の関数は、引数が'...'で囲まれているmvコマンドを生成します。

3
yrk

これを行う小さなスクリプトは次のとおりです。

for var in `find . -type f -name "*(1).m4a"`; do
    new=`echo $var | cut -d'(' -f1`;
    mv $var $new.m4a;
done
1
anupam