बैश स्क्रिप्ट में यूनिकोड के लिए grep कैसे करें


11
if grep -q "�" out.txt
    then
        echo "working"
    else
        cat out.txt
fi

असल में, यदि फ़ाइल "out.txt" में फ़ाइल में कहीं भी "file" है, तो मैं इसे "वर्किंग" कहना चाहता हूं और यदि फ़ाइल "out.txt" में फ़ाइल में कहीं भी " " नहीं है, तो मैं चाहूंगा यह बिल्ली से बाहर है

संपादित करें: तो यहाँ मैं क्या कर रहा हूँ। मैं एक खुलने वाले डिक्रिप्ट को बल देने की कोशिश कर रहा हूं।

खुलता है एनएस 0 रिटर्न सफलता पर, गैर-शून्य अन्यथा। नोट: आपको झूठी सकारात्मकता मिलेगी क्योंकि एईएस / सीबीसी केवल यह निर्धारित कर सकता है कि पैडिंग सही होने के आधार पर "डिक्रिप्शन काम करता है"। तो फाइल डिक्रिप्ट हो जाती है लेकिन यह सही पासवर्ड नहीं होगा, इसलिए इसमें यह अस्पष्ट होगा। जिबरिश में एक सामान्य चरित्र "g" है। इसलिए मैं चाहता हूं कि यदि उत्पादन में "loop" हो तो लूप को जारी रखें।

Heres my git लिंक https://github.com/Raphaeangelo/OpenSSLCracker Heres the script

while read line
do
openssl aes-256-cbc -d -a -in $1 -pass pass:$line -out out.txt 2>out.txt >/dev/null && printf "==================================================\n"
if grep -q "�" out.txt
    then
        :
    else
        cat out.txt &&
            printf "\n==================================================" &&
            printfn"\npassword is $line\n" &&
            read -p "press return key to continue..." < /dev/tty; 
fi
done < ./password.txt

इसके अभी भी मुझे इसमें ic charicter के साथ आउटपुट दिखा रहा है

अद्यतन: हल

printf "Working..."

while read line
do
openssl aes-256-cbc -d -a -in $1 -pass pass:$line -out out.txt 2>out.txt >/dev/null
if file out.txt | grep -q 'out.txt: ASCII text'
    then
        printf "\n==================================================\n\n" &&
            cat out.txt &&
            printf "\n==================================================" &&
            printf "\npassword is $line\n" && 
            read -p "press return key to continue..." < /dev/tty;
    else
        : 
fi
done < ./password.txt

यह सही लगता है, यह काम करना चाहिए (btw, मुझे आपके यूनिकोड चरित्र को देखने के लिए कोई फ़ॉन्ट नहीं है, लेकिन उनमें से किसी का भी कोई अर्थ नहीं है)। grepलंबे समय से यूनिकोड को समझता है (जो इसे बहुत धीमा बनाता है, इसलिए एससीआई स्ट्रिंग्स की खोज करना, LANG=C grepएक बहुत बड़ा प्रदर्शन सुधार है)।
पीटर - मोनिका

मुझे इसे हटाना पड़ सकता है और एक और प्रश्न पोस्ट करना होगा क्योंकि मुझे यकीन है कि मैं यहां सभी को पूरी तरह से भ्रमित कर रहा हूं।
स्टुअर्ट स्लोन

@Stuart स्लोअन आपके प्रश्न का शीर्षक How to grep for unicode � in a bash scriptक्या यह वास्तव में आप चाहते हैं? यूनिकोड निकालने के लिए? कृपया स्पष्ट करें ताकि हम मदद कर सकें!

1
@ गोरो मैंने अपने मूल पोस्ट का संपादन किया है। मुझे उम्मीद है कि यह समझ में आता है। कृपया मुझे बताएं कि क्या यह नहीं है और मैं स्पष्ट करने की कोशिश करूंगा।
स्टुअर्ट स्लोन

1
दोनों उपस्थित उत्तर बेहद भ्रामक हैं। कृपया (फिर से) मेरे उत्तर को पढ़ें , मैंने इसे संपादित करने के लिए समझाया है कि वाह दोनों उत्तरों के साथ गलत है।
इसहाक

जवाबों:


27

grep नौकरी के लिए गलत उपकरण है।

आप, U+FFFD REPLACEMENT CHARACTERनहीं देखते हैं क्योंकि यह फ़ाइल सामग्री में शाब्दिक रूप से है, लेकिन क्योंकि आपने एक बाइनरी फ़ाइल को एक उपकरण के साथ देखा है जो केवल पाठ-आधारित इनपुट को संभालने वाला है। अमान्य इनपुट (यानी, यादृच्छिक बाइनरी डेटा) को संभालने का मानक तरीका यह है कि स्क्रीन को हिट करने से पहले U + FFFD के साथ वर्तमान लोकेल (जो शायद UTF-8) में मान्य नहीं है।

इसका मतलब है कि यह बहुत संभावना है कि एक शाब्दिक \xEF\xBF\xBD(यूटीएफ-एफएफएफडी चरित्र के लिए यूटीएफ -8 बाइट अनुक्रम) फ़ाइल में कभी नहीं होता है। grepआपको बताने में पूरी तरह सही है, कोई भी नहीं है।

यह पता लगाने का एक तरीका है कि क्या फ़ाइल में कुछ अज्ञात बाइनरी है जो file(1)कमांड के साथ है :

$ head -c 100 /dev/urandom > rubbish.bin
$ file rubbish.bin
rubbish.bin: data

किसी भी अज्ञात फ़ाइल प्रकार के लिए यह बस कहेगा data। प्रयत्न

$ file out.txt | grep '^out.txt: data$'

यह जांचने के लिए कि क्या फ़ाइल में वास्तव में कोई मनमाना बाइनरी है और इस तरह सबसे अधिक संभावना बकवास है।

यदि आप यह सुनिश्चित करना चाहते हैं कि out.txtकेवल UTF-8 एन्कोडेड पाठ फ़ाइल है, तो आप वैकल्पिक रूप से उपयोग कर सकते हैं iconv:

$ iconv -f utf-8 -t utf-16 out.txt >/dev/null

आप बिलकुल सही कह रहे हैं! दुर्भाग्य से, मैं अभी भी आउटपुट में कुछ (पहले से कम) बकवास कर रहा हूं।
स्टुअर्ट स्लोन

संभवतः fileउन फ़ाइलों के लिए कुछ अन्य सामग्री प्रकार का पता लगाता है। यदि आप 100% हमेशा केवल UTF-8 एन्कोडेड पाठ फ़ाइलों की अपेक्षा करते हैं iconv, तो आप एक फ़ाइल मान्य UTF-8: के साथ देख सकते हैं iconv -f utf-8 -t utf-16 out.txt >/dev/null। यदि iconvफ़ाइल को अवैध UTF-8 अनुक्रमों के कारण परिवर्तित नहीं किया जा सकता है, तो यह एक गैर-शून्य निकास कोड के साथ वापस आ जाएगी।
बोल्ड्यूवेन

2
फ़ाइल कमांड सही था! आपने मुझे मेरे मुद्दे को हल करने में मदद की धन्यवाद!
स्टुअर्ट स्लोन

4
बेशक कि grep "नौकरी के लिए उपकरण है", कोशिश करें grep -axv '.*' badchars.txt। वह किसी भी लाइन को प्रिंट करेगा जिसमें कोई भी अवैध यूनिकोड कैरेक्टर है।
इसहाक

1
यह बेहद भ्रामक है, कृपया मेरे उत्तर में पढ़ें कि क्या fileकरता है।
इसहाक

5

टी एल; डॉ:

grep -axv '.*' out.txt 

लंबा जवाब

दोनों उपस्थित उत्तर बेहद भ्रामक और मूल रूप से गलत हैं।

परीक्षण करने के लिए, इस दो फ़ाइलों को प्राप्त करें (बहुत अच्छी तरह से विकसित डेवलपर से: मार्कस कुह्न):

$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt

डेमो

पहला UTF-8-demo.txtएक फ़ाइल है जिसे यह दिखाने के लिए डिज़ाइन किया गया है कि UTF-8 कितनी भाषाओं, गणित, ब्रेल और कई अन्य उपयोगी प्रकारों को प्रस्तुत करने में सक्षम है। एक टेक्स्ट एडिटर के साथ एक नज़र डालें (जो utf-8 को समझते हैं) और आप बहुत सारे उदाहरण देखेंगे और नहीं

परीक्षण जो एक उत्तर का प्रस्ताव करता है: चरित्र सीमा को सीमित करने के लिए \x00-\x7Fइस फ़ाइल के अंदर लगभग सब कुछ अस्वीकार कर देगा।
यह बहुत गलत है और इसे कोई दूर नहीं करेगा क्योंकि उस फ़ाइल में कोई भी नहीं है

उस उत्तर में सुझाए गए परीक्षण का उपयोग करके 72.5 %फ़ाइल को हटा दिया जाएगा :

$ grep -oP "[^\x00-\x7F]" UTF-8-demo.txt | tr -d '\n' | wc -c
10192
$ cat UTF-8-demo.txt | wc -c
14058

वह (अधिकांश व्यावहारिक उद्देश्यों के लिए) संपूर्ण फ़ाइल है। पूरी तरह से वैध पात्रों को दिखाने के लिए बहुत अच्छी तरह से डिज़ाइन की गई फ़ाइल।

परीक्षा

दूसरी फ़ाइल कई बॉर्डर मामलों की पुष्टि करने के लिए डिज़ाइन की गई है कि utf-8 पाठक एक अच्छा काम कर रहे हैं। इसमें कई वर्ण शामिल हैं जो एक 'be' का कारण बनेंगे। लेकिन उपयोग करने के लिए अन्य उत्तर अनुशंसा (चयनित एक) fileइस फ़ाइल के साथ सकल रूप से विफल हो जाती है। केवल एक शून्य बाइट ( \0) (जो तकनीकी रूप से मान्य ASCII है) और एक \x7fबाइट (DEL - हटाएं) (जो स्पष्ट रूप से एक ASCII वर्ण है) को हटाकर सभी फ़ाइल को fileकमांड के लिए वैध बना देगा :

$ cat UTF-8-test.txt | tr -d '\0\177' > a.txt
$ file a.txt 
a.txt: Non-ISO extended-ASCII text, with LF, NEL line terminators

इतना ही नहीं कईfile का पता लगाने में विफल रहता है गलत अक्षर, लेकिन यह भी पता लगाने और रिपोर्ट के लिए यह एक UTF-8 एन्कोडेड फ़ाइल है कि असफल।

और हां, fileUTF-8 एन्कोडेड पाठ का पता लगाने और रिपोर्ट करने में सक्षम है:

$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text

इसके अलावा, file1 से 31 की सीमा में ASCII के अधिकांश नियंत्रण वर्णों के रूप में रिपोर्ट करने में विफल रहता है। यह ( file) कुछ श्रेणियों के रूप में रिपोर्ट करता है data:

$ printf '%b' "$(printf '\\U%x' {1..6})" | file -
/dev/stdin: data

दूसरों के रूप में ASCII text:

$ printf '%b' "$(printf '\\U%x' 7 {9..12})" | file -
/dev/stdin: ASCII text

मुद्रण योग्य चरित्र श्रेणी के रूप में (नईलाइन्स के साथ):

$ printf '%b' "$(printf '\\U%x' {32..126} 10)" | file -
/dev/stdin: ASCII text

लेकिन कुछ सीमाएँ अजीब परिणाम दे सकती हैं:

$ printf '%b' "$(printf '\\U%x' {14..26})" | file -
/dev/stdin: Atari MSA archive data, 4113 sectors per track, starting track: 5141, ending track: 5655

कार्यक्रम fileपाठ का पता लगाने के लिए एक उपकरण नहीं है, बल्कि निष्पादन योग्य कार्यक्रमों या फाइलों में जादू की संख्या का पता लगाने के लिए है ।

पर्वतमाला का fileपता लगाने, और इसी प्रकार की रिपोर्ट के अनुसार मैं पाया गया था:

  • एक बाइट मान, ज्यादातर एस्की:

    {1..6} {14..26} {28..31} 127   :data
    {128..132} {134..159}          :Non-ISO extended-ASCII text
    133                            :ASCII text, with LF, NEL line terminators
    27                             :ASCII text, with escape sequences
    13                             :ASCII text, with CR, LF line terminators
    8                              :ASCII text, with overstriking
    7 {9..12} {32..126}            :ASCII text
    {160..255}                     :ISO-8859 text
    
  • Utf-8 एन्कोडेड पर्वतमाला:

    {1..6} {14..26} {28..31} 127   :data
    27                             :ASCII text, with escape sequences
    13                             :ASCII text, with CR, LF line terminators
    8                              :ASCII text, with overstriking
    7 {9..12} {32..126}            :ASCII text
    {128..132} {134..159}          :UTF-8 Unicode text
    133                            :UTF-8 Unicode text, with LF, NEL line terminators
    {160..255}                     :UTF-8 Unicode text
    {256..5120}                    :UTF-8 Unicode text
    

एक संभव समाधान नीचे निहित है।


पिछला उत्तर

आपके द्वारा पोस्ट किए जा रहे चरित्र के लिए यूनिकोड मान है:

$ printf '%x\n' "'�"
fffd

हां, यह एक यूनिकोड कैरेक्टर 'रिप्लेसमेंट चार्ज' (U + FFFD) है । यह एक ऐसा चरित्र है जिसका उपयोग पाठ में पाए जाने वाले किसी भी अमान्य यूनिकोड चरित्र को बदलने के लिए किया जाता है । यह एक "दृश्य सहायता" है, वास्तविक चरित्र नहीं। प्रत्येक पूर्ण पंक्ति को खोजने और सूचीबद्ध करने के लिए जिसमें अमान्य UNICODE वर्ण हैं:

grep -axv '.*' out.txt 

लेकिन अगर आप केवल यह जानना चाहते हैं कि कोई भी चरित्र अमान्य है, तो उपयोग करें:

grep -qaxv '.*' out.txt; echo $?

यदि परिणाम 1फ़ाइल साफ है, अन्यथा शून्य होगा 0


यदि आप जो पूछ रहे थे वह था: चरित्र को कैसे खोजना है , तो, इस का उपयोग करें:

➤ a='Basically, if the file "out.txt" contains "�" anywhere in the file I'
➤ echo "$a" | grep -oP $(printf %b \\Ufffd)
�

या यदि आपकी प्रणाली सही ढंग से UTF-8 पाठ की प्रक्रिया करती है, तो बस:

➤ echo "$a" | grep -oP '�'
�

OMG आपको बहुत बहुत धन्यवाद grep -axv '.*' !! मैंने अपनी पाठ फ़ाइलों में कुछ बुरे पात्रों के साथ संघर्ष किया है, और उन्हें एक या दो दशक के लिए emacs में कैसे ठीक किया जाए !!!
nealmcb

3

यह बहुत ही प्रारंभिक उत्तर मूल पद के लिए था जो था:

बैश स्क्रिप्ट में यूनिकोड के लिए grep कैसे करें

if grep -q "�" out.txt
    then
        echo "working"
    else
        cat out.txt  fi

असल में, यदि फ़ाइल "out.txt" में फ़ाइल में कहीं भी "file" है, तो मैं इसे "वर्किंग" कहना चाहता हूं और यदि फ़ाइल "out.txt" में फ़ाइल में कहीं भी " " नहीं है, तो मैं चाहूंगा यह बिल्ली से बाहर है

प्रयत्न

grep -oP "[^\x00-\x7F]"

एक if .. thenबयान के साथ इस प्रकार है:

if grep -oP "[^\x00-\x7F]" file.txt; then
    echo "grep found something ..."
else
    echo "Nothing found!"
fi

Explanation💡:

  • -P, --perl-regexp: पैटर्न एक पर्ल रेगुलर एक्सप्रेशन है
  • -o, --only-matching : एक लाइन से मेल खाते नमूने का ही हिस्सा दिखाने
  • [^\x00-\x7F] एक एकल गैर-एएससीआईआई चरित्र से मेल खाने वाला रेक्स है।
  • [[:ascii:]] - एक ASCII चार से मेल खाता है
  • [^[:ascii:]] - एक एकल गैर- ASCII चार से मेल खाता है

में bash

LC_COLLATE=C grep -o '[^ -~]' file

3
जैसे ही कोई अंग्रेजी नहीं बोलता है, तो यह टूट जाएगा (एक झूठी सकारात्मक है) ...
केविन

या अगर कोई ला कार्टे, इमोजी, पोकेमोन, या किसी अन्य चीज़ पर चर्चा करने की कोशिश करता है, जो 7bit ASCII से कड़ाई से सीमित नहीं है। 09-1 ए 0 डी (टैब, लाइनफीड, गाड़ी वापसी) को छोड़कर 00-1F में किसी भी चीज़ के लिए बेहतर देखो।
अल्करो

यह एक बहुत ही बुरा विचार है। यह ASCII रेंज के ऊपर किसी भी वैध यूनिकोड चार को अस्वीकार कर देगा , केवल एक लाख वैध वर्णों से थोड़ा अधिक। गजब का। कोशिश करें: printf '%b' "$(printf '\\U%x' {128..131})" | grep -oP "[^\x00-\x7F]"सिर्फ 4 वैध यूनिकोड वर्ण जो आपके कोड को अस्वीकार करते हैं। :-(
इसहाक

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