मैंने नीचे बैश स्क्रिप्ट को लागू किया, यह मेरे लिए काम करता है।
यह पहले iconv
एन्कोडिंग से वापस आने की कोशिश करता file --mime-encoding
है utf-8
।
यदि वह विफल हो जाता है, तो यह सभी एन्कोडिंग के माध्यम से जाता है और मूल और पुनः एन्कोडेड फ़ाइल के बीच के अंतर को दिखाता है। यह उन एन्कोडिंग्स पर छोड़ देता है जो एक बड़े अंतर वाले आउटपुट ("बड़े" को MAX_DIFF_LINES
वैरिएबल या दूसरे इनपुट तर्क के रूप में परिभाषित करते हैं ), क्योंकि वे सबसे अधिक गलत एन्कोडिंग हैं।
यदि इस स्क्रिप्ट का उपयोग करने के परिणामस्वरूप "खराब चीजें" होती हैं, तो मुझे दोष न दें। वहाँ एक rm -f
है, तो वहाँ राक्षस हो। मैंने एक यादृच्छिक प्रत्यय के साथ फाइलों पर इसका उपयोग करके प्रतिकूल प्रभावों को रोकने की कोशिश की, लेकिन मैं कोई वादा नहीं कर रहा हूं।
डार्विन पर परीक्षण 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