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」で始まりますが、ここではさまざまな名前の多くの画像があります。「safe」で置き換える文字列の「#U00a9」の部分をターゲットにしているだけです。
これは難しくありません。逆スラッシュ(\)を前に付けることで、名前のoctothorpe(#)を必ずエスケープしてください。
find . -type f -name 'Lucky-*' | while read FILE ; do
newfile="$(echo ${FILE} |sed -e 's/\\#U00a9/safe/')" ;
mv "${FILE}" "${newfile}" ;
done
現在のディレクトリ(再帰的ではない)のファイル名の#
をsomethingelse
に置き換えるには、 GNU rename ユーティリティを使用します。
rename 's/#/somethingelse/' *
-
のような文字は、\
でエスケープする必要があります。
あなたのケースでは、あなたが使いたいでしょう
rename 's/#U00a9/safe/g' *
*.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 renameは homebrew を使用してインストールできます:brew install rename
。
ファイルのリストを見つけて、キーワードを置き換えます。以下は例です
find . -name '*jpg' -exec bash -c ' mv $0 ${0/\#U00a9NBC/safeNBC}' {} \;
脱出する #
シェルから、単一引用符('#'
)、二重引用符("#"
)、またはバックスラッシュ(\#
)。
あなたの場合、最も簡単なのはrename
コマンドを使用することです(利用可能な場合):
rename '#U00a9' safe *.jpg
sedする方法はわかりませんが、bashシェルでこれを試すことができます。
for f in Lucky-#U00a9NBC-*.jpg; do mv -v "$f" "${f/#U00a9/safe}"; done;
説明:
パラメーター置換の詳細(IMOは十分に活用されていません): http://www.tldp.org/LDP/abs/html/parameter-substitution.html
上記の例は私のシステム(CentOS 5.6)では機能しなかったので、機能する(おそらくシステム固有の)コマンドが見つかりました(注:コマンドラインで\
を使用して '#'をエスケープする必要があります)。
rename \#U00a9 safe *.jpg
[また、コメントする評判がまだないため、/g
でのrename 's/old_string/new_string/g'
の使用に関するNikhilの質問(上記の別の回答のコメントに記載)に応じて:
g
修飾子を使用して、「グローバル」置換を実行します(つまり、old_stringが発生する回数だけ、old_stringをnew_stringに置き換えます)。 rename
は*
で指定されたすべてのファイルに適用されるため、これは私の答えでは必要ありません。この修飾子と他の修飾子の簡潔な説明については、 https://www.computerhope.com/unix/rename.htm を参照してください。]
以下は、再利用可能な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
実際、rename
には--subst
または-s
と呼ばれるものとまったく同じオプションがあります。正規表現構文を使用する必要はありません。
rename -s '#U00a9' 'safe' *
複数のオカレンスを置換/置換する場合は、--subst-all
または-S
を使用します。
ところで、私は文字列を何も置き換えないだけでした(ファイル名から削除しました)... -d/--delete
と-D/--delete-all
のオプションもあります:
rename -d '#U00a9' *
次の手順を実行します
ls Lucky-#U00a9NBC*.jpg
すべてのjpg
ファイル名をLucky-#U00a9NBC*
で表示します
rename 's/Lucky-#U00a9NBC/Lucky-safeNBC/' *.jpg
このコマンドを実行した後、すべてのLucky-#U00a9NBC
をLucky-safeNBC
に置き換えます。
ls Lucky-safeNBC*.jpg
すべてのファイルの名前が変更されていることがわかります
#U00a9
は、ここでU + 00A9の文字(©
)を表すことを意図している可能性が高いと思います。
ロケールの文字セットでエンコードされた©
に戻したい場合は、Perl
のrename
バリアント(prename
と呼ばれることもある)を使用できます。
rename '
use Encode::Locale;
use Encode;
s/#U([0-9a-f]{4})/chr hex $1/gie;
$_ = encode(locale_fs => $_)' ./*'#'[uU]*