結合されたUnicode文字の検索と置換

結合されたUnicode文字の検索と置換

äディレクトリ名とファイル名にいくつかの「特殊」文字(、、、öüが含まれているDebianシステムには深いフォルダ構造があります。ただし、これは「ISO-8859-1」ではなく、Unicode結合文字の形です。私が知っている限り、a 2つの点(分音符/ウムラウト)を「別の」文字として追加するのは簡単な問題です。

findとsedを使用して、すべてのファイルとフォルダの名前を一括変更してみました。

#!/bin/bash

# Files - normal characters
find . -depth -name "*[äöüÄÖÜ]*" -exec bash -c 'mv "$1" "$(echo $1 | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} \;
# Files - Unicode combining characters
find . -depth -name "*[äöüÄÖÜ]*" -exec bash -c 'mv "$1" "$(echo $1 | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} \;

# Directories - normal characters
find . -depth -type d -name "*[äöüÄÖÜ]*" -exec bash -c 'mv "$1" "$(echo $1 | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} \;
# Directories - Unicode combining characters
find . -depth -type d -name "*[äöüÄÖÜ]*" -exec bash -c 'mv "$1" "$(echo $1 | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} \;

ただし、引数のパラメータがISO-8859-1の代わりにUnicodeに結合されている場合、ファイル/フォルダ名に表示さfindれるすべての項目も選択されているようです。例えば、aä-nameä

$ find . -name "*[ä]*"  //<-- one letter ä
./filename_one_letter_ä
$ find . -name "*[ä]*"  //<-- combining letter ä
./filename_with_just_a
./filename_one_letter_ä
./filename_with_combining_diaeresis_ä

したがって、  sedファイル名を変更せずに渡すので、たとえば、""から""にmv名前を変更するように要求するときに文句を言います(つまり、ソースとターゲットは同じです)。BaustandBaustand

findを使用して検索できない場合、Linuxシステムのファイル/フォルダ構造内でUnicode、、、、、のすべての組み合わせäを検索して置き換える方法は?試してみる別の方法はありますか?öüÄÖÜ

私のファイルとディレクトリ名の例は次のとおりです。

/Projekte/03-11_Törggel_Mammern/Baustand/03-11_Törggel-Baustand_190501_0009.jpg

名前を次に変更したいです。

/Projekte/03-11_Toerggel_Mammern/Baustand/03-11_Toerggel-Baustand_190501_0009.jpg

出力echo $LANGはですen_US.UTF-8

ベストアンサー1

このATMを再現(またはテスト)することはできませんが...

まあ、あなたは[xyz]一致を知っています。x または y または z。私の考えでは、(結合文字を使用して)言うとき、[äöü…]それは見ていると思います。

  • a
  • (結合する) ¨
  • o
  • (結合する) ¨
  • u
  • (結合する) ¨

aしたがって、名前に、、oを含むファイルを探します。u または(組合せ)  ¨、必ずしもそうではないがまたは 

したがって、別々に参照してください。

find . -depth -name "*ä*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/ä/ae/g")"' _ {} ';'
find . -depth -name "*ö*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/ö/oe/g")"' _ {} ';'
find . -depth -name "*ü*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/ü/ue/g")"' _ {} ';'
find . -depth -name "*Ä*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/Ä/Ae/g")"' _ {} ';'
find . -depth -name "*Ö*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/Ö/Oe/g")"' _ {} ';'
find . -depth -name "*Ü*" -exec bash -c 'mv "$1" "$(echo "$1" | sed -e "s/Ü/Ue/g")"' _ {} ';'

(角かっこを除く)。一部のファイル名では(引用符を除く)がecho $1失敗する可能性があります。 (';'同等\;。スタイル上のバックスラッシュを避けることをお勧めします。)

またはあなたが本物本物1 つのコマンドですべての操作を実行するには、次のようにします。

find . -depth "(" -name "*ä*" -o -name "*ö*" -o -name "*ü*"     \
               -o -name "*Ä*" -o -name "*Ö*" -o -name "*Ü*" ")" \
       -exec bash -c 'mv "$1" "$(printf "%s" "$1" | sed -e "s/ä/ae/g; s/ö/oe/g; s/ü/ue/g; s/Ä/Ae/g; s/Ö/Oe/g; s/Ü/Ue/g")"' _ {} ';'

printf "%s"機能的には非常に似ていますechoが、より安全です。スタイル的には通常(二重引用符を含む)を使用します。ここでは、単一引用符()文字列内にあるprintf '%s'ため、二重引用符を使用します。)'mv …'

可能

… "(" -iname "*ä*" -o -iname "*ö*" -o -iname "*ü*" ")" …

動作します。


LANGまた、最初に試したジョブをに設定すると機能することがありますde_DE.UTF-8

おすすめ記事