web-dev-qa-db-ja.com

ファイル名の文字エンコードの問題-壊れたファイル名を見つける

このQ&A で説明されている問題があります。かなり古いLinuxディストリビューションまたはWindowsから、壊れたファイル名のファイルがいくつかあります。 lsは「?」を表示します壊れた文字の代わりに。これらのファイルのいくつかは正常に名前を変更しましたが、それらのすべてを見つけたかどうかはわかりません。

影響を受けるすべてのファイルを見つける方法はありますか?

5
lumbric

Utf-8エンコーディング(Ubuntuのデフォルト)を使用していると仮定すると、このスクリプトはファイル名を識別して名前を変更することを期待します。

Cエンコード(ascii)でfindを使用して、印刷できない文字が含まれるファイルを見つけます。次に、これらの印刷できない文字がutf-8文字かどうかを判断しようとします。そうでない場合は、enc配列にリストされている各エンコードでデコードされたファイル名が表示され、名前を変更するために適切なものを選択できます。

latin1は古いLinuxシステムで一般的に使用されていましたが、windows-1252は最近ではwindowsで一般的に使用されています(私は思う)。 iconv -lは、可能なエンコードのリストを表示します。

#!/bin/bash

# list of encodings to try. (max 10)
enc=( latin1 windows-1252 )

while IFS= read -rd '' file <&3; do
    base=${file##*/} dir=${file%/*}

    # if converting from utf8 to utf8 succeeds, we'll assume the filename is ok.
    iconv -f utf8 <<< "$base" >/dev/null 2>&1 && continue

    # display the filename converted from each enc to utf8
    printf 'In %s:\n' "$dir/"
    for i in "${!enc[@]}"; do
        name=$(iconv -f "${enc[i]}" <<< "$base")
        printf '%2d - %-12s: %s\n' "$i" "${enc[i]}" "$name"
    done
    printf ' s - Skip\n'

    while true; do
        read -p "? " -n1 ans
        printf '\n'
        if [[ $ans = [0-9] && ${enc[ans]} ]]; then
            name=$(iconv -f "${enc[ans]}" <<< "$base")
            mv -iv "$file" "$dir/$name"
            break
        Elif [[ $ans = [Ss] ]]; then
            break
        fi
    done
done 3< <(LC_ALL=C find . -depth -name "*[![:print:][:space:]]*" -print0)
10
geirha

これを試して:

find / | grep -P "[\x80-\xFF]"

これにより、ファイル名とフォルダー名に含まれるすべての非ASCII文字が検索され、犯人を見つけるのに役立ちます。

2
SirCharlo

この正規表現のfindコマンドから始めて、興味のあるfind . | egrep [^a-zA-Z0-9_./-\s]のみがヒットするまで変更します。
上記のコマンドは、UTF-8以外の文字を含むファイル名を検索します。

1
yossile