Saya menerapkan skrip bash di bawah, ini berfungsi untuk saya.
Pertama kali mencoba iconv
dari pengkodean yang dikembalikan oleh file --mime-encoding
ke utf-8
.
Jika gagal, ia akan melewati semua penyandian dan menunjukkan perbedaan antara file asli dan yang disandikan ulang. Itu melompati pengkodean yang menghasilkan keluaran diff besar ("besar" seperti yang didefinisikan oleh MAX_DIFF_LINES
variabel atau argumen input kedua), karena mereka kemungkinan besar pengkodean yang salah.
Jika "hal buruk" terjadi akibat menggunakan skrip ini, jangan salahkan saya. Ada rm -f
di sana, jadi ada monster. Saya mencoba untuk mencegah efek buruk dengan menggunakannya pada file dengan akhiran acak, tetapi saya tidak membuat janji.
Diuji pada Darwin 15.6.0.
#!/bin/bash
if [[ $# -lt 1 ]]
then
echo "ERROR: need one input argument: file of which the enconding is to be detected."
exit 3
fi
if [ ! -e "$1" ]
then
echo "ERROR: cannot find file '$1'"
exit 3
fi
if [[ $# -ge 2 ]]
then
MAX_DIFF_LINES=$2
else
MAX_DIFF_LINES=10
fi
#try the easy way
ENCOD=$(file --mime-encoding $1 | awk '{print $2}')
#check if this enconding is valid
iconv -f $ENCOD -t utf-8 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo $ENCOD
exit 0
fi
#hard way, need the user to visually check the difference between the original and re-encoded files
for i in $(iconv -l | awk '{print $1}')
do
SINK=$1.$i.$RANDOM
iconv -f $i -t utf-8 $1 2> /dev/null > $SINK
if [ $? -eq 0 ]
then
DIFF=$(diff $1 $SINK)
if [ ! -z "$DIFF" ] && [ $(echo "$DIFF" | wc -l) -le $MAX_DIFF_LINES ]
then
echo "===== $i ====="
echo "$DIFF"
echo "Does that make sense [N/y]"
read $ANSWER
if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ]
then
echo $i
exit 0
fi
fi
fi
#clean up re-encoded file
rm -f $SINK
done
echo "None of the encondings worked. You're stuck."
exit 3