名前を変更したいファイルを含むフォルダーがいくつかあります
Foo'Bar - Title
に
Title
OS X 10.7 を使用しています。私は他の解決策を見てきましたが、再帰にうまく対処しているものはありません。
助言がありますか?
名前を変更したいファイルを含むフォルダーがいくつかあります
Foo'Bar - Title
に
Title
OS X 10.7 を使用しています。私は他の解決策を見てきましたが、再帰にうまく対処しているものはありません。
助言がありますか?
問題には 2 つの部分があります: 再帰的に操作するファイルを見つけることと、それらの名前を変更することです。
最初に、すべてが現在のディレクトリのちょうど 1 レベル下にある場合、現在のディレクトリ内のすべてのディレクトリの内容を一覧表示するだけで済みます (上記の Mattias Wadman の回答のように) が、より一般的には (そしておそらくより理解しやすく、起動するには)、 findコマンドを使用するだけです。
2 つ目は、sed を使用して、引用符とパイピングを適切に処理する方法を見つけることができますが (最終的には必ず習得する必要があります)、 renameコマンドを使用する方がはるかに簡単です。残念ながら、これは Mac には組み込まれていませんが、Homebrew などでインストールするか、perl スクリプトとsudo install -m755 rename /usr/local/bin/rename
.
したがって、これを行うことができます:
find . -exec rename 's|[^/]* - ||' {} +
正しいことを確認するために「予行演習」を行いたい場合は、「-n」フラグを追加して名前を変更します。
find . -exec rename -n 's|[^/]* - ||' {} +
それがどのように機能するかを理解するには、find のチュートリアルと rename のマンページを読んでください。
find .
「現在のディレクトリの下ですべてのファイルを再帰的に見つける」ことを意味します。-type f
通常のファイル以外をすべてスキップしたい場合や、'Title' で終わるファイルのみを変更したい場合は `-name '*Title') が、これは必須ではありません。あなたの使用のために。-exec
…は、見つかったファイルをまとめて、「…」に表示されるコマンド+
の any の代わりにできるだけ多くのファイルを渡すことを意味します。{}
rename 's|[^/]* - ||' {}
{} 内の各ファイルに対して、perl 式s|[^/]* - ||
をファイル名に適用し、結果が異なる場合は、その結果に名前を変更することを意味します。s|[^/]* - ||
正規表現 ' [^/]* -
' に一致し、一致を '' (空の文字列) に置き換えることを意味します。[^/]* -
' - ' で終わる非スラッシュ文字の任意の文字列に一致することを意味します。したがって、' ./A/FooBar - Title
' では、' ' に一致しますFooBar -
。このように何か複雑なことをしなければならない場合、数分後に find/sed/awk/rename/etc. でそれを正しくしようとしても、まだうまくいかないことがよくあります。 Python と os.walk を使って命令的にコーディングするだけです。Python を知っている場合は、Python の方が理解しやすく (より冗長で単純ではありませんが)、他のユース ケースに変更するのも簡単です。興味がある場合は、そのように尋ねてください。
これを試して:
ls -1 * | while read f ; do mv "$f" "`echo $f | sed 's/^.* - //'`" ; done
コマンドが正常に見えるように、実行するecho
前にa を追加することをお勧めします。mv
abarnert がコメントで指摘したように、このコマンドは一度に 1 つのディレクトリに対してのみ機能します。
さまざまなコマンドの詳細な説明:
ls -1 *
現在のディレクトリ内の各ファイル (およびディレクトリ) の行を出力します ( .
-files を除く)。したがって、これは に展開されls -1 file1 file2 ...
、ファイル名のみと 1 行に 1 つのファイルをリストするよう-1
に指示します。ls
出力は次にパイプされ、ファイルの終わりに達するまでwhile read f ; ... ; done
ループし、0 を返します。は、標準入力 (この場合は からの出力) から一度に 1 行を読み取り、指定された変数 (この場合は ) に格納します。read f
read f
ls -1 ...
f
while ループではmv
、2 つの引数を指定してコマンドを実行します。1 つ目"$f"
はソース ファイル (スペースなどを含むファイル名を処理するための引用符に注意してください) として、2 つ目は sed と ` (バッククォート) を使用してコマンド置換と呼ばれるものを実行する宛先ファイル名です。バッククォート内でコマンドを呼び出し、標準出力からの出力に置き換えます。
echo $f | sed 's/^.* - //'
現在のファイルを sed にパイプします。$f
これは正規表現に一致し、置換 ( s
in s/
) を行い、結果を標準出力に出力します。正規表現は^.* -
、文字列の先頭から一致し^
(アンカーと呼ばれます)、その後に.*
続く任意の文字に一致し、-
それを空の文字列 ( の間の文字列//
) に置き換えます。
試行錯誤の末、同じ問題を解決するのに役立つこのソリューションに出会いました。
find <dir> -name *.<oldExt> -exec rename -S .<oldExt> .<newExt> {} \;
基本的に、私は検索ユーティリティと名前変更ユーティリティを活用しています。ここでのコツは、rename の '{}' (rename によって処理する必要があるファイルを表す) をどこに配置するかを考え出すことです。
PS の名前変更は、組み込みの Linux ユーティリティではありません。私はOS Xで作業しており、homebrewを使用して名前の変更をインストールしました。