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


13

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

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

some_song.m4a

some_song(1).m4a

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

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

これfind . -name *\(1\).m4aにより、変換されたすべてのFLACファイルが取得されます。

次の私は、私が何かを知っている-execし、mvすべての見つかったファイルの名前を変更します。しかし、私が理解できないのは、元のファイル名を保持し、単に削除する方法(1)です。

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

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


5
なぜ下票なのか?有効な質問のようです...

特定の質問(on find)とは無関係ですが、実際の問題(オーディオファイルの変換)を解決している可能性があります。audiotools.sourceforge.netとこの例(macosx lion)invibe.net/をご覧ください。 LaurentPerrinet / SciBlog / 2012-04-22
meduz

回答:


13

find最後の手段として以外は、出力を解析しようとしないでください。Unixファイルシステムでは、ファイル名は文字列(一般的な誤解)ではなく、null文字以外の任意の文字を含むバイナリblobであることに注意することが重要/です。正しく安全にファイル名を解析するとすると、時間の99%はあなたが完全にそれをやって避けたいだけだろうと痛みのに十分である(ちょうど毛深い方法を見てsedで表現@ yarekの答えは、すべてのケースをカバーしていないことさえあり) 。ありがたいことに、この場合、はるかに簡単なアプローチがあります。

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

きちんとしたアプローチまだsed式として毛深い:) +1
yrk

1
ここに何かがありません...どこにありdoneますか?
-yrk

@yarekキャッチしてくれてありがとう。これとsedパイプのアプローチの最大の違いは、これがはるかに安全であることです。基本的なシェルスクリプト構造を理解していれば、正規表現のバックスラッシュスープよりも読みやすくなります。
jw013

あなたが正しい; これはずっときれいです。また、$arg変数を使用すると読みやすくなります。
hobbes3

1
@DQdlM上に投稿したスニペットは、かなり移植性のあるPOSIX構文でfind呼び出しshているだけです。詳細については、パラメーター拡張セクション、forループを説明する複合コマンドセクション、およびPOSIX find仕様を確認できます。これらのリソースに加えて、具体的なご質問があればお気軽にお答えします。
jw013

6

DebianとUbuntuでは、私はrename 's/\(1\)//' *.m4aあなたの問題を解決するために使用できます。


奇妙なは、私が行うことができますman renameが、私は実際にはありませんrename-bash: rename: command not foundwhich rename何も表示されません)。
hobbes3

ここのMacの@ hobbes3は、rename(2)-syscall 、およびrename(n)-TCLコマンドをman -a rename見つけます。どちらもあります名前変更(1)やユーティリティ自体が。
yrk

1
IIRC renameは、一部のperlインストールに含まれるサンプルに含まれるperlスクリプトです。いくつかのディストリビューションでは、便利なコマンドであるため、パスに含まれています。(@Hobbesはおそらくインターネットで見つけることができます)
ケビン

私のシステムの@Kevin renameは通常のバイナリです(perlではありません)。ただし、別の警告として、すべてのバージョンがrename正規表現をサポートしているわけではありません。例えば、私が持っているバージョンは、あなたが例えば、直接文字列の置換、行うことができますrename '(1)' '' *.m4a
パトリック・

1
Perl renameスクリプトは、Debianおよび派生物によってのみインストールされます。他のLinuxシステムには異なるrenameユーティリティがあります(Patrickが示しています)。OSXにはどちらもありません。
ジル 'SO-悪であるのをやめる

4

zshでは、zmvを使用します

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

2番目の引数(新しい名前)で、ソースパターンの括弧で囲まれたグループ$1$2参照し(PATTERN)ます。この名前の変更を記述する別の方法は

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

3

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

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'\'/

最初の関数は、すべて''...'-escaped文字列の途中で文字どおりに取得されるような形式に変換します。2番目の関数は、引数がで囲まれたmvコマンドを生成します'...'


1
このコマンドは、ファイル名(スペース、、(その他すべての特殊文字)をエスケープしたり、ファイル名の前後に引用符を追加したりしません。コマンドを変更しようとしましたが、mvコマンドの両方のファイル名を引用符で囲む方法がわかりませんでした。コマンドの結果の出力の1つはmv ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us(1).m4a ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us.m4aです。私はそのコマンドを実行した場合、私が得ます-bash: syntax error near unexpected token '('
-hobbes3

これは宿題になるはずです:)
わかりました

ところで、GNU sedはe、置換後にコマンドを追加することにより、コマンド自体を実行できます。たとえば、find . -name '*(1).m4a' | sed 's/\(.*\)(1).m4a$/mv & \1.m4a/e'にパイプせずにコマンドを実行しsh -xます。
ラッシュ

@Rushはそれを行う唯一のsedです。とにかくシェルを起動する必要がありますが、各コマンドごとに新しいものが必要です(makeの問題を思い出しますよね?)
yrk

2
私たちは投票するべきではないと思います。結局のところ、これは有効な解決策です。
hobbes3

1

これを行う小さなスクリプトを次に示します。

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

これは、名前にスペースが含まれるファイルで停止します。また、それがために十分な大きさの一時保管が必要です`find ...`
Yrkを含む
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.