सशर्त रूप से यूटीएफ -8 में भर्ती कैसे करें?


2

मैं अलग-अलग कंप्यूटरों पर समय के साथ इकट्ठा हुई पाठ फ़ाइलों के एक बड़े समूह के एन्कोडिंग को एकजुट कर रहा हूं। मैं मुख्यतः ISO-8859-1 से UTF-8 जा रहा हूँ। यह अच्छी तरह से एक फ़ाइल धर्मान्तरित:

recode ISO-8859-1..UTF-8 file.txt

मैं निश्चित रूप से सभी फाइलों के लिए स्वचालित बैच प्रसंस्करण करना चाहता हूं, और बस प्रत्येक फ़ाइल के लिए उपरोक्त चलाने से समस्या होती है कि फाइलें किसकी हैं पहले से UTF-8 में एन्कोडेड, उनके एन्कोडिंग को तोड़ा जाएगा। (उदाहरण के लिए, ISO-8859-1 में मूल रूप से 'ä' वर्ण इस तरह दिखाई देगा, जिसे UTF-8 के रूप में देखा जाता है, यदि उपरोक्त रिकोड दो बार किया गया है: � -> ä -> ä )

मेरा सवाल यह है कि, जरूरत पड़ने पर ही किस तरह की स्क्रिप्ट फिर से शुरू होगी , अर्थात। केवल उन फ़ाइलों के लिए जो पहले से ही एन्कोडिंग में नहीं थीं (UTF-8 मेरे मामले में)?

रिकोड मैन पेज को देखने से, मैं समझ नहीं पा रहा था कि मैं ऐसा कुछ कैसे कर सकता हूं। इसलिए मुझे लगता है कि यह आसानी से किसी फ़ाइल की एन्कोडिंग की जांच करने के लिए या कम से कम अगर यह UTF-8 है या नहीं, तो यह उबालता है। यह उत्तर तात्पर्य आप मान्य यूटीएफ -8 फाइलों को रिकोड के साथ पहचान सकते हैं, लेकिन कैसे? किसी भी अन्य उपकरण भी ठीक होगा, जब तक कि मैं एक सशर्त स्क्रिप्ट में परिणाम का उपयोग कर सकता हूं ...


नोट: मैंने सवालों की तरह देखा है superuser.com/questions/27060/... और वे करते हैं नहीं इस विशेष प्रश्न का उत्तर प्रदान करें।
Jonik

जवाबों:


7

यह संदेश काफी पुराना है, लेकिन मुझे लगता है कि मैं इस समस्या में योगदान कर सकता हूं:
पहले एक स्क्रिप्ट बनाएं जिसका नाम है recodeifneeded :

#!/bin/bash
# Find the current encoding of the file
encoding=$(file -i "$2" | sed "s/.*charset=\(.*\)$/\1/")

if [ ! "$1" == "${encoding}" ]
then
# Encodings differ, we have to encode
echo "recoding from ${encoding} to $1 file : $2"
recode ${encoding}..$1 $2
fi

आप इसे इस तरह से उपयोग कर सकते हैं:

recodeifneeded utf-8 file.txt

इसलिए, यदि आप इसे पुनरावर्ती रूप से चलाना और सभी * .txt फ़ाइलों को एन्कोड करना चाहते हैं (चलो कहते हैं) utf-8:

find . -name "*.txt" -exec recodeifneeded utf-8 {} \;

आशा है कि ये आपकी मदद करेगा।


2
केवल समाधान जो मूल एन्कोडिंग की परवाह किए बिना काम करता है।
Jr. Hames

3

यह स्क्रिप्ट, से अनुकूलित harrymc का विचार , जो एक फ़ाइल को सशर्त रूप से पुनरावर्ती करता है (कुछ UTF-8 एन्कोडेड स्कैंडिनेवियाई वर्णों के अस्तित्व के आधार पर), मेरे लिए अच्छी तरह से काम करने लगता है।

$ cat recode-to-utf8.sh 

#!/bin/sh
# Recodes specified file to UTF-8, except if it seems to be UTF-8 already

result=`grep -c [åäöÅÄÖ] $1` 
if [ "$result" -eq "0" ]
then
    echo "Recoding $1 from ISO-8859-1 to UTF-8"
    recode ISO-8859-1..UTF-8 $1 # overwrites file
else
    echo "$1 was already UTF-8 (probably); skipping it"
fi

(बैच प्रोसेसिंग फाइलें बेशक ईजी का एक साधारण मामला है। for f in *txt; do recode-to-utf8.sh $f; done।)

एनबी : यह पूरी तरह से स्क्रिप्ट फ़ाइल पर ही निर्भर करता है जो UTF-8 है। और जैसा कि यह स्पष्ट रूप से एक बहुत ही सीमित समाधान है कि मेरे पास किस प्रकार की फाइलें हैं, बेहतर उत्तर जोड़ने के लिए स्वतंत्र महसूस करें जो समस्या को अधिक सामान्य तरीके से हल करते हैं।


2

UTF-8 के सख्त नियम हैं जिनके बारे में बाइट क्रम मान्य हैं। इसका मतलब है कि अगर डेटा सकता है UTF-8 हो, अगर आपको लगता है कि शायद ही आपको गलत सकारात्मक जानकारी मिलेगी है

तो आप ऐसा कुछ कर सकते हैं (अजगर में):

def convert_to_utf8(data):
    try:
        data.decode('UTF-8')
        return data  # was already UTF-8
    except UnicodeError:
        return data.decode('ISO-8859-1').encode('UTF-8')

एक शेल स्क्रिप्ट में, आप उपयोग कर सकते हैं iconv बातचीत करने के लिए, लेकिन आपको UTF-8 का पता लगाने के साधन की आवश्यकता होगी। एक तरीका है उपयोग करना iconv स्रोत और गंतव्य एन्कोडिंग दोनों के रूप में UTF-8 के साथ। यदि फ़ाइल UTF-8 मान्य थी, तो आउटपुट इनपुट के समान होगा।


धन्यवाद, उपयोगी लगता है - मैं अगली बार यह कोशिश करूँगा जब बैच पाठ फ़ाइलों को परिवर्तित कर रहा हो
Jonik

1

ISO-8859-1 और UTF-8 दोनों पहले 128 वर्णों पर समान हैं, इसलिए आपकी समस्या वास्तव में ऐसी फ़ाइलों का पता लगाने की है जिसमें मज़ेदार वर्ण हैं, जिसका अर्थ संख्यात्मक रूप से 128 के ऊपर एन्कोडेड है।

यदि मजेदार वर्णों की संख्या अत्यधिक नहीं है, तो आप स्कैन करने और यह पता लगाने के लिए egrep का उपयोग कर सकते हैं कि किन फ़ाइलों को रीकोड करने की आवश्यकता है।


दरअसल, मेरे मामले में "मजाकिया चरित्र" ज्यादातर फिनिश में इस्तेमाल किए जाने वाले åäö (+ अपरकेस) हैं। यह काफी यह सरल है, लेकिन मैं इस विचार को अनुकूलित कर सकता हूं ... मैं UTF-8 टर्मिनल का उपयोग कर रहा हूं, और उदा। 'ä' इसे खोजता है केवल उन फ़ाइलों में जो पहले से ही UTF-8 हैं (यानी बहुत ही फाइलें जिन्हें मैं छोड़ना चाहता हूं)! इसलिए मुझे इसके विपरीत करना चाहिए: फाइलों को फिर से लिखना जहां grep लगता है कोई नहीं [äÄöÖåÅ] की । ज़रूर, इन फ़ाइलों में से कुछ के लिए (शुद्ध ascii) recoding आवश्यक नहीं है, लेकिन यह या तो कोई फर्क नहीं पड़ता। फिर भी, इस तरह से मैं शायद उन सभी फ़ाइलों को प्राप्त कर लूंगा जो पहले से ही थीं, बिना यूटीएफ -8 के। मैं इसे कुछ और परीक्षण करूँगा ...
Jonik

1

मुझे थोड़ी देर हो गई है, लेकिन मैं बार-बार एक ही सवाल के साथ संघर्ष कर रहा हूं ... अब जब कि मुझे यह करने का एक शानदार तरीका मिल गया है, मैं मदद नहीं कर सकता, लेकिन इसे साझा करूंगा :)

एक एमएसीएस उपयोगकर्ता होने के बावजूद, मैं आपको आज विम का उपयोग करने की सलाह दूंगा।

इस सरल कमांड के साथ, यह आपकी फ़ाइल को फिर से बनाएगा, चाहे जो भी वांछित एन्कोडिंग के अंदर हो:

vim +'set nobomb | set fenc=utf8 | x' <filename>

मुझे इससे बेहतर परिणाम देने वाला कुछ नहीं मिला।

मुझे उम्मीद है कि यह कुछ अन्य लोगों की मदद करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.