ファイル名の文字列を置き換えて複数のファイルの名前を変更する方法は?この文字列には「#」が含まれます


42

https://serverfault.com/questions/70939/how-to-replace-a-text-string-in-multiple-files-in-linux

https://serverfault.com/questions/228733/how-to-rename-multiple-files-by-replacing-word-in-file-name

https://serverfault.com/questions/212153/replace-string-in-files-with-certain-file-extension

https://serverfault.com/questions/33158/searching-a-number-of-files-for-a-string-in-linux

これらの言及された記事はすべて私の質問に答えました。しかし、それらのどれも私のために機能しません。置換しようとしている文字列に#が含まれているためと思われます。これに対処する特別な方法はありますか?

サイトの移行中にéが#U00a9に置き換えられたイメージファイルがあります。これらは次のようになります。

Lucky-#U00a9NBC-80x60.jpg
Lucky-#U00a9NBC-125x125.jpg
Lucky-#U00a9NBC-150x150.jpg
Lucky-#U00a9NBC-250x250.jpg
Lucky-#U00a9NBC-282x232.jpg
Lucky-#U00a9NBC-300x150.jpg
Lucky-#U00a9NBC-300x200.jpg
Lucky-#U00a9NBC-300x250.jpg
Lucky-#U00a9NBC-360x240.jpg
Lucky-#U00a9NBC-400x250.jpg
Lucky-#U00a9NBC-430x270.jpg
Lucky-#U00a9NBC-480x240.jpg
Lucky-#U00a9NBC-600x240.jpg
Lucky-#U00a9NBC-600x250.jpg
Lucky-#U00a9NBC.jpg

そして、私はそれを次のようなものに変更したい:

Lucky-safeNBC-80x60.jpg
Lucky-safeNBC-125x125.jpg
Lucky-safeNBC-150x150.jpg
Lucky-safeNBC-250x250.jpg
Lucky-safeNBC-282x232.jpg
Lucky-safeNBC-300x150.jpg
Lucky-safeNBC-300x200.jpg
Lucky-safeNBC-300x250.jpg
Lucky-safeNBC-360x240.jpg
Lucky-safeNBC-400x250.jpg
Lucky-safeNBC-430x270.jpg
Lucky-safeNBC-480x240.jpg
Lucky-safeNBC-600x240.jpg
Lucky-safeNBC-600x250.jpg
Lucky-safeNBC.jpg

更新:

これらの例はすべて「LU00a9ucky」で始まりますが、ここには異なる名前の多くの画像があります。文字列の「#U00a9」の部分をターゲットとして「safe」に置き換えています。


3
実際に何を試しましたか?あなたはいくつかの質問にリンクしていて、それらは失敗したと言っていますが、どのように失敗しましたか?IMOの最良の例ではrenameコマンドを使用しています。名前の変更はのように簡単だと思いますrename -n 's/#/safeNBC/' *.jpg
ゾレダチェ14

試しましたがrename -n 's/#U00a9/safe/' *.jpg、コマンドは受け入れられましたが、変更は発生しませんでした。

確かに、あなたが確実にレビューしたドキュメントからわかるように、これ-nno actオプションです。これにより、実際に使用する前に機能するかどうかを確認できます。画面の出力には、潜在的な新しい名前が正しく表示されましたか?
ゾレダチェ14

私はあなたの例をコピーして貼り付けて謝罪しました。@DTKは問題に対処していると思います。#をエスケープしていませんでした。

MacOSでファイル名に文字列を置き換える:superuser.com/questions/152627/...
アントンタラセンコ

回答:


64

交換する#ことにより、somethingelseカレントディレクトリ(再帰的ではない)あなたが使用することができます内のファイル名のためのGNUリネームユーティリティ:

rename  's/#/somethingelse/' *

のような文字-は、でエスケープする必要があります\

あなたの場合、あなたは使いたいでしょう

rename 's/#U00a9/safe/g' *

特定のファイルの選択(たとえば、only)のみ*.jpgを操作する場合は、その選択に一致するように最終入力を調整することに注意してください。

rename 's/#U00a9/safe/g' *.jpg

実際にファイル名を変更する前にテストを実行するには、次の-nフラグを使用します。

demo/> ls                               
Lucky-#U00a9NBC-125x125.jpg  
Lucky-#U00a9NBC-150x150.jpg 

demo/> rename -n 's/#U00a9/safe/g' *.jpg
rename(Lucky-#U00a9NBC-125x125.jpg, Lucky-safeNBC-125x125.jpg)
rename(Lucky-#U00a9NBC-150x150.jpg, Lucky-safeNBC-150x150.jpg)

OS Xの場合は、GNUの名前変更を使用してインストールすることができ自作をbrew install rename


これは私のマシン(Arch Linux)では動作しませんでしたが、mikの答えは動作しました。
-marcvangend

@marcvangendどのバージョンrenameを使用していますか? # sudo pacman -S perl-renameperlバージョンをインストールします。これはより強力で、この回答を機能させるのに十分かもしれません。
ジョン・ガワー

@JohnGowersありがとう!2つのバージョンがあることに気づきませんでした。私のシステムでrename --versionrename from util-linux 2.29.2、実際にはperlバージョンではないので戻ります。
marcvangend

5
一般的なrenameユーティリティは2つありますが、どちらもGNUによって開発されたものではありません。DebianベースのディストリビューションにはrenamePerlパッケージのユーティリティが含まれ、Red HatベースのディストリビューションにはLinux Kernel Organizationのrenameユーティリティが使用されますutil-linux。リンクは、GNU標準ライブラリのrenameC 関数へのリンクです。
アンソニーG-モニカの正義

2
この回答では、なぜ我々は書く必要がない/grename 's/#U00a9/safe/g' *
ニキル

21

ファイルのリストを見つけて、キーワードを置き換えます。以下は例です

find . -name '*jpg' -exec bash -c ' mv $0 ${0/\#U00a9NBC/safeNBC}' {} \;

1
あなたの周りにいくつかの二重引用符必要があるmv場合に、名前にスペースがある、引数を
ストップハニングモニカ

すべてのファイル* _spec.rbを* _controller_spec.rbに置き換える必要がありましたが、あなたのソリューションは私のために働きました。ありがとう
ジェディ

18

これは難しくありません。逆スラッシュ(\)を前に付けて、名前のオクトソープ(#)を必ずエスケープしてください。

find . -type f -name 'Lucky-*' | while read FILE ; do
    newfile="$(echo ${FILE} |sed -e 's/\\#U00a9/safe/')" ;
    mv "${FILE}" "${newfile}" ;
done 

あなたの説明は理にかなっています、#私が必要とするもののように音を逃れます。あなたの例にはバックスラッシュはありません。次のようになりますか? s/\#U00a9/safe/

@LeonFrancisShelhamer良いキャッチ。バックスラッシュを飲み込んだ。変更します。

17

#シェルからエスケープするには、単一引用符('#')、二重引用符("#")、または円記号(\#)を使用します。

あなたの場合の最も簡単な方法は、renameコマンドを使用することです(使用可能な場合)。

rename '#U00a9' safe *.jpg

2
ありがとう。rename 's/#/somethingelse/' *私のマシン(Arch Linux)では、最高の回答()が機能しませんでしたが、これは機能しました。
-marcvangend

1
これは、util-linuxのrenameコマンドを使用して機能します。
imclean

10

sedの実行方法がわかりませんが、bashシェルでこれを試すことができます。

for f in Lucky-#U00a9NBC-*.jpg; do mv -v "$f" "${f/#U00a9/safe}"; done;

説明:

  1. グロブ(Lucky-#U00a9NBC-*。jpg)に一致するすべてのファイル名をループします
  2. moveコマンド(mv)を使用してファイルの名前を変更します
  3. ネイティブbashパラメーター置換$ {var / Pattern / Replacement}を使用して、新しい名前を作成します( "$ {f /#U00a9 / safe}")

パラメーターの置換の詳細(使用率が非常に低いIMO):http : //www.tldp.org/LDP/abs/html/parameter-substitution.html


このコードは質問に答えるかもしれませんが、それ自体ではあまり役に立ちません。問題を解決する方法を説明すると、回答の有用性と長期的な価値が向上します。
アンソニーG-モニカの正義

Anthonyのコメントに従って、ウォークスルーの説明と詳細な説明を追加しました。
グレゴリーパトモア

1

上記の例は私のシステム(CentOS 5.6)では機能していなかったので、機能する(おそらくシステム固有の)コマンドを見つけました(注:\コマンドラインで「#」をエスケープする必要があります)。

rename \#U00a9 safe *.jpg

[も:私はの使用に関するのでニキルの質問に応じて、コメントにはまだ十分な評判を持っていない/grename 's/old_string/new_string/g'(別の答え上記のコメントで提起します):

使用g(発生old_stringに何度でもold_stringにするためにnew_stringを代用すること、である)「グローバル」置換を実行するためにモディファイアを。これは、でrename指定されたすべてのファイルに適用されるため、私の答えでは必要ないはず*です。これと他の修飾子の簡潔な説明については、https://www.computerhope.com/unix/rename.htmを参照してください。]


正しい; CentOSのようなFedora派生OSにはrename、Debian派生OS とは異なるバージョンがあります。unix.stackexchange.com/a/238862/135943を参照してください。ところで、CentOS 5.6はかなり古いので、アップグレードすることをお勧めします。
ワイルドカード

ああ、説明+リンクをありがとう。時代遅れのOSが働いているので、それをアップグレードするために、私までではありません:)が、新しいクラスタが出て建設されていると我々は上に移動するとき、おそらく私たちはアップグレードよ...
エズラ・シトロン

0

再利用可能なbash関数に包まれたDTKのソリューションは次のとおりです。

function renameFilesRecursively () {

  SEARCH_PATH="$1"
  SEARCH="$2"
  REPLACE="$3"

  find ${SEARCH_PATH} -type f -name "*${SEARCH}*" | while read FILENAME ; do
      NEW_FILENAME="$(echo ${FILENAME} | sed -e "s/${SEARCH}/${REPLACE}/g")";
      mv "${FILENAME}" "${NEW_FILENAME}";
  done

}

使用方法は次のとおりです。

renameFilesRecursively /home/user/my-files apple orange

0

実際にrename呼び出された、--substまたは-s簡単にそれのためのオプションがあります 正規表現構文を使用する必要はありません。

rename -s '#U00a9' 'safe' *

複数のオカレンスを置換/置換する場合は、--subst-allまたはを使用します-S

ところで、私は何もして文字列を置換したい(ファイル名から削除)...よく我々はまた、そのためのオプションを持っている-d/--delete-D/--delete-all

rename -d '#U00a9' *

-1

別のオプションはpyRenamer、バッチ名前変更専用に作成されたアプリケーションを使用することです。

でインストールできます sudo apt-get install pyrenamer

使用方法の詳細については、GitHubのREADMEファイルを参照しください。


1
これで質問に答えられると本当に思う場合は、答えに説明を追加してください。それ自体は、パッケージのみをインストールします。コマンドの機能を説明し、OPの特定の要件を処理する例を提供する必要があります。
ロアイマ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.