web-dev-qa-db-ja.com

bashスクリプトでunicodeをgrepする方法

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

基本的に、ファイル「out.txt」にファイル内のどこかに「�」が含まれている場合、「機能」をエコーし​​たい場合、およびファイル「out.txt」にファイル内のどこにも「�」が含まれていない場合は、 cat out.txtに

編集:これが私がやっていることです。私はopenssl復号化をブルートフォースにしようとしています。

openssl encは成功すると0を返し、それ以外の場合はゼロ以外を返します。注:AES/CBCはパディングを正しく行うことに基づいて「復号化が機能する」かどうかしか判断できないため、誤検知が発生します。そのため、ファイルは復号化されますが、正しいパスワードではないため、意味不明なものになります。意味不明な言葉の一般的な文字は「�」です。したがって、出力に「�」が含まれている場合は、doループを続行する必要があります。

Heres my git link 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

その中に�文字が含まれた出力が表示されます

更新:解決済み

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
10
Stuart Sloan

grepは、ジョブには不適切なツールです。

_U+FFFD REPLACEMENT CHARACTER_ が表示されるのは、文字どおりファイルの内容に含まれているからではなく、テキストベースの入力のみを処理することになっているツールでバイナリファイルを調べたためです。無効な入力(つまり、ランダムバイナリデータ)を処理する標準的な方法は、現在のロケール(ほとんどの場合、UTF-8)で無効なものをすべて画面に表示する前にU + FFFDに置き換えることです。

つまり、リテラル_\xEF\xBF\xBD_(U + FFFD文字のUTF-8バイトシーケンス)がファイル内で発生しない可能性が非常に高いです。 grepは完全に正しいと言っています。何もありません。

ファイルに不明なバイナリが含まれているかどうかを検出する1つの方法は、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
_
27
Boldewyn

TL; DR:

grep -axv '.*' out.txt 

長い答え

現在の両方の答えは非常に誤解を招きやすく、基本的に間違っています。

テストするには、次の2つのファイルを入手してください(非常に評価の高い開発者:Markus Kuhnから):

$ 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を理解する)テキストエディターで見てみると、多くの例とnoが表示されます。

1つの回答が提案するテスト:文字範囲を\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

これは(ほとんどの実用的な目的では)ファイル全体です。完全に有効な文字を表示するように非常によく設計されたファイル。

テスト

2番目のファイルは、いくつかの境界ケースを試し、utf-8リーダーが適切に機能していることを確認するように設計されています。 「�」が表示される原因となる多くの文字が内部に含まれています。しかし、fileを使用するための他の回答の推奨(選択されたもの)は、このファイルでは著しく失敗します。ゼロバイト(\0)(技術的には有効なASCII)と\x7fバイト(DEL-削除)(これは明らかにASCII文字でもある)を削除するだけです。 )は、allファイルを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エンコードされていることの検出と報告にも失敗しますファイル。

そして、はい、fileはUTF-8でエンコードされたテキストを検出して報告できます。

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

また、fileは、ASCII 1〜31の範囲のほとんどの制御文字)として報告できません。それは(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は、テキストを検出するためのツールではなく、実行可能プログラムまたはファイル内のmagic番号を検出するためのツールです。

検出された範囲fileと、私が見つけた対応するタイプは次のとおりです:

  • 1バイト値、主にascii:

    {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
    

考えられる解決策の1つは以下のとおりです。


以前の回答。

投稿する文字のUnicode値は次のとおりです。

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

はい、それは nicode Character 'REPLACEMENT CHARACTER'(U + FFFD) です。これは、テキストで見つかった無効なUnicode文字を置き換えるために使用される文字です。それは「視覚的な援助」であり、本当の性格ではありません。無効な[〜#〜] 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 '�'
�
5
Isaac

この非常に早い答えは元の投稿に対するものでした:

Bashスクリプトでunicodeをgrepする方法

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

基本的に、ファイル「out.txt」にファイル内のどこかに「�」が含まれている場合、「機能」をエコーし​​たい場合、およびファイル「out.txt」にファイル内のどこにも「�」が含まれていない場合は、 cat 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

説明????:

  • -P--Perl-regexp:PATTERNはPerl正規表現です
  • -o--only-matching:PATTERNに一致する行の部分のみを表示します
  • [^\x00-\x7F]は、単一の非ASCII文字に一致する正規表現です。
  • [[:ascii:]]-単一のASCII charに一致します
  • [^[:ascii:]]-単一の非ASCII文字と一致します

bash

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