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
不明なファイル形式の場合は、単にdata
Tryと表示されます。
$ 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でエンコードされたファイルであることを検出して報告することはできません。
はい、file
UTF-8でエンコードされたテキストを検出して報告できます。
$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text
さらに、file
1〜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でエンコードされたストリームに再組み立てする方法など、より大きな例で説明されています。