長い答え

長い答え
if grep -q "�" out.txt
    then
        echo "working"
    else
        cat out.txt
fi

デフォルトでは、「out.txt」ファイルにファイルの任意の場所に「�」が含まれている場合は「WORK」をエコーし​​、「out.txt」ファイルにファイルのどこにも「�」が含まれていない場合欲しいです。猫を追い出す。txt

編集:これが私がすることです。無差別代入OpenSSLの復号を試みています。

openssl encは成功した場合は0を返し、それ以外の場合は0以外の値を返します。注:AES / CBCは正しいパディングに基づいて「暗号解読が有効かどうか」のみを確認できるため、誤検出が発生します。したがって、ファイルは復号化されますが、正しいパスワードではないため、横説説が含まれます。歪んだ文字の一般的な文字は「�」です。したがって、出力に「�」が含まれている場合は、doループを続行したいと思います。

これは私の子リンクですhttps://github.com/Raphaeangelo/OpenSSLCracker これはスクリプトです。

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

それでも、文字を含む出力が表示されます。

答え1

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

不明なファイル形式の場合は、単にdataTryと表示されます。

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

ファイルに実際にランダムなバイナリが含まれていることを確認してください。したがって、ガベージである可能性が高いです。

UTF-8でエンコードされたテキストファイルであることを確認するには、次のものを使用することもout.txtできますiconv

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

答え2

簡単に言うと:

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を理解するテキストエディタを使って見てみましょう。いいえ

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バイト(\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バイト値(主に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

うん、それは一つです。Unicode文字「代替文字」(U + FFFD)。すべての文字を置き換えるために使用される文字です。無効テキストにUnicode文字があります。実際のキャラクターというよりは「視覚的補助物」だ。無効なコンテンツを含むすべての行全体を見つけて一覧表示します。Unicode使用されたキャラクター:

grep -axv '.*' out.txt 

ただし、無効な文字があるかどうかを検索するには、次のようにします。

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

結果が1ファイルがきれいである場合は0です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 '�'

答え3

この最初の答えは元の投稿への答えです。

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

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

デフォルトでは、「out.txt」ファイルにファイルの任意の場所に「�」が含まれている場合は「WORK」をエコーし​​、「out.txt」ファイルにファイルのどこにも「�」が含まれていない場合欲しいです。猫を追い出す。txt

努力する

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

氏名はif .. then次のとおりです。

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

説明する

答え4

エンコーディング変換を実行するツール「iconv」と、生のバイナリを16進数に変換する「xxd」ツールを使用して、この問題を解決できました。シェルが追加のロジックを含まずに実際のUnicode文字コードポイントを解決できるように、ファイルをUTF-32 BE(ビッグエンディアン)バイトストリームに変換します。

このリクエスト例では、ファイル内の単一のUnicode文字の存在のみを検出します。文字が\u1234abcd(間違っていますが、これは単なる例です)と仮定します。

# iconv does its best to detect the encoding and convert it to UTF-32 BE
iconv -t utf32be out.txt | \
# xxd turns the raw binary into hex digits and some new lines.
# The '-g 1' attempts to avoid local computer endian-ness by grouping 1
# byte at a time.  It may not be necessary.
xxd -g 1 -R never -ps | \
# 'tr' strips out whitespace generated by 'xxd'.
tr -d '\r\n ' | \
# Loop over each 8 hex digit character.
# This causes the shell to read the input stream
# 8 characters at a time which, if everything above
# went right, is limited to 0-9 and a-f.  LANG=C
# just enforces 1 byte at a time.
while IFS='' LANG=C read -r -d '' -n 8 char ; do
  if [ "${char}" = "1234abcd" ] ; then
    echo "working"
    # No need to scan any other character.  Exit early.
    break
  fi
done

主な質問とは異なり、上記の回答は見つからない場合は後続の実行を実行しませんcat out.txt。これを行うには、内部実行の外部で見つかった状態を渡す必要があります。私の一般的なアプローチは、ファイルが存在する場合に表示することです。一部の進取者は、子プロセスと終了コードを使用してgrepと同様のアプローチを見つけることもできます。

# Create the marker file.
marker="$( mktemp )"

iconv -t utf32be out.txt | \
xxd -g 1 -R never -ps | \
tr -d '\r\n ' | \
while IFS='' LANG=C read -r -d '' -n 8 char ; do
  if [ "${char}" = "1234abcd" ] ; then
    echo "working"
    # Mark that it was found by removing the temporary file.
    rm "${marker}"
    break
  fi
done

# If the marker file exists, then it wasn't found in the loop.
if [ -f "${marker}" ] ; then
  rm "${marker}"
  cat out.txt
fi

16進数だけを生成し、エンディアン変換を避けるように非常に注意している場合は、「xxd」の代わりに「od」または「hexdump」を使用できます。

「xxd」は、元のデータを返すリバース機能を提供するという利点がある。 "echo -e "\xAf""スタイルの出力を使用して同じことを実行できますが、これを行うには、解析された各文字に対して新しいエコーパスを作成する必要があります。

私はこれを入れました主なポイントこれは、出力をUTFでエンコードされたストリームに再組み立てする方法など、より大きな例で説明されています。

関連情報