次の特殊文字を含むファイルを含む複数のディレクトリとサブディレクトリがあります。
robbie@phil:~$ ls test�sktest.txt
test?sktest.txt
検索はエスケープシーケンスを表します。
robbie@phil:~$ find test�sktest.txt -ls
424512 4000 -rwxr--r-x 1 robbie robbie 4091743 Jan 26 00:34 test\323sktest.txt
コンソールに名前を入力できる唯一の理由は、タブの完成によるものです。これは、手動で名前を変更したり特殊文字を削除したりすることができます。
LC_ALLをUTF-8に設定しましたが、役に立たないようです(新しいシェルでも役に立ちません)。
robbie@phil:~$ echo $LC_ALL
en_US.UTF-8
私のMacでコンピュータに接続するためにSSHを使用しています。 Ubuntuのインストールは次のとおりです。
robbie@phil:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=7.10
DISTRIB_CODENAME=gutsy
DISTRIB_DESCRIPTION="Ubuntu 7.10"
シェルは Bash で、TERM は xterm-color に設定されます。
このファイルは長い間存在しており、Ubuntuインストールを使用して作成されませんでした。そのため、システムエンコーディングの設定が何であるかはわかりません。
私は以下を試しました:
find . -type f -ls | sed 's/[^a-zA-Z0-9]//g'
しかし、私が望むすべてのことを行うソリューションを見つけることができません。
- 表示できない文字を含むすべてのファイルを識別します(あまりにも多くの文字は上で無視されます)。
- ディレクトリツリー内のすべてのファイルに対して(再帰的に)mv oldname newnameを実行します。
- (オプション)特殊文字(例:ä)をa(必須ではありませんが役に立ちます)に変換します。
または
- これらのファイルはすべて正しく表示されます(ファイルを開こうとするとアプリケーションにエラーがありません)。
すべてのファイルを繰り返す、移動するなど、いくつかの問題がありますが、ファイルを識別してmvコマンドに正しくフォーマットするのは難しい部分のようです。
正しく表示されない理由や、正しいエンコーディングを「推測する」方法に関する追加情報も歓迎します。 (convmvを試しましたが、まさに私が望むように動作しないようです。http://j3e.de/linux/convmv/)
答え1
�
名前に無効なUTF-8バイトシーケンスが含まれているため、この無効な文字が表示されるようです。一般的なUnixファイルシステム(ユーザーシステムを含む)のファイル名はバイト文字列であり、使用するエンコーディングの決定はアプリケーションによって異なります。最近UTF-8の使用は傾向になっていますが、普遍的ではありません。特に、純粋なASCIIが不可能なロケールとUTF-8が存在する前に他のエンコーディングが使用されている地域ではさらにそうです。
LC_CTYPE=en_US.iso88591 ls
ISO-8859-1(latin-1)でファイル名が適切であることを確認してください。そうでない場合は、別のロケールを試してください。LC_CTYPE
ここでは、ロケールだけが重要です。
UTF-8ロケールでは、次のコマンドは有効なUTF-8以外の名前を持つすべてのファイルを表示します。
grep-invalid-utf8 () {
perl -l -ne '/^([\000-\177]|[\300-\337][\200-\277]|[\340-\357][\200-\277]{2}|[\360-\367][\200-\277]{3}|[\370-\373][\200-\277]{4}|[\374-\375][\200-\277]{5})*$/ or print'
}
find | grep-invalid-utf8
他のロケールでより意味があるかどうかを確認できます。録音または賞:
find | grep-invalid-utf8 | recode latin1..utf8
find | grep-invalid-utf8 | iconv -f latin1 -t utf8
複数のファイル名が特定のエンコーディング(latin1など)になっていることを確認した後、名前を変更する1つの方法は次のとおりです。
find | grep-invalid-utf8 |
rename 'BEGIN {binmode STDIN, ":encoding(latin1)"; use Encode;}
$_=encode("utf8", $_)'
これはパールを使用します名前を変更するこのコマンドはDebianとUbuntuで利用できます。-n
実際にファイル名を変更せずに何をすべきかを示すためにこれを渡すことができます。
答え2
私はこれが古い質問であることを知っていますが、一晩中同様の解決策を探していました。私はいくつかの便利なヒントを見つけましたが、私のニーズにぴったりではなかったので、私が探していた正しい結果を得るためにいくつかのヒントを混ぜ合わせて一致させる必要がありました。
特殊文字を削除して(.)ドットに置き換えます。
for f in *.txt; do mv "$f" `echo $f | sed "s/[^a-zA-Z0-9.]/./g"`; done
cronjobで使用するために毎分実行される次のことを行いました。
*/1 * * * * cd /path/to/files/ && for f in *.txt; do mv "$f" `echo $f | sed "s/[^a-zA-Z0-9.]/./g"`; done >/dev/null 2>&1
誰かがこれが私を幸せにしてくれるので役に立つことを願っています:)
答え3
これで、リモート側のファイル名にどのエンコーディングが使用されるかを知っている場合(「latin1」 - 最初の回答の説明に従って)、次のこともできます。2番目の方法- ローカル端末を実行してSSHこのようにリモートファイル名が正しく表示されます(最初の方法:名前を変更する代わりに)。。
良い私、次のように特定のエンコーディングで動作する端末をローカルで起動できます。
LC_ALL=en_US.latin1 xvt &
xvt
端末プログラムを表します。
たぶん、私は既存のロケールをそう呼んでいますが、私が仮定したものではないen_US.iso88591
かもしれません。en_US.latin1
答え4
これは一括要件を満たしていませんが、同じ名前の複数のバージョンのファイルがあり、奇妙な文字だけが他の同様の問題に直面しました。残念ながら、これは犯罪者の名前を変更するために一般的なワイルドカードトリックを使用できないことを意味します。
最後に、FilezillaをSFTPクライアントとして接続し、ファイルを参照し、GUIを使用して名前を変更しました。 Filezillaは疑わしい文字を非常によく扱います。