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 循环继续进行。
这是我的 git 链接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
不是因为它确实存在于文件内容中,而是因为您使用应该仅处理基于文本的输入的工具查看了二进制文件。处理无效输入(即随机二进制数据)的标准方法是在输入屏幕之前用 U+FFFD 替换当前语言环境中无效的所有内容(最有可能是 UTF-8)。
这意味着文件中很可能永远不会出现文字\xEF\xBF\xBD
(U+FFFD 字符的 UTF-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
答案2
长话短说:
grep -axv '.*' out.txt
长答案
目前的两个答案都极具误导性,而且基本上是错误的。
要进行测试,请获取这两个文件(来自一位备受推崇的开发人员: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)看一下,你会看到很多例子和不 �
。
一个答案提出的测试:将字符范围限制为\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 阅读器做得很好。它包含许多字符,这些字符会导致显示“�”。但是要使用的另一个答案建议(所选的答案)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 编码的文件。
是的,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
和报告的相应类型是:
一字节值,主要是 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
一种可能的解决方案如下。
以前的答案。
您发布的字符的 Unicode 值为:
$ printf '%x\n' "'�"
fffd
是的,那是一个Unicode 字符 '替换字符' (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 '�'
�
答案3
这个非常早期的答案是针对原始帖子的:
如何在 bash 脚本中 grep 查找 unicode �
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
解释
答案4
我能够通过使用工具“iconv”执行编码转换和“xxd”将原始二进制转换为十六进制数字来解决这个问题。它将文件转换为 UTF-32 BE(大端)字节流,以便 shell 可以检查真正的 Unicode 字符代码点,而无需包含额外的逻辑。
该示例请求仅检测文件中是否存在单个 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
与主要问题不同,上面的答案不会执行后续操作(如果未找到),则 run 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
如果您非常小心地只生成十六进制数字并避免字节序转换,则可以使用“od”或“hexdump”代替“xxd”。
“xxd”的优点是提供返回原始数据的反向功能。可以使用“echo -e“\xAf””样式输出来完成同样的事情,但这需要为每个解析的字符生成一个新的回显过程。
我把这个放进去要点以更大的示例来展示它,包括如何将输出重新组装成 UTF 编码流。