在bash脚本中找到仅包含可打印字符的文件

时间:2010-09-21 09:26:40

标签: bash grep non-printable

我正在尝试编写一个bash脚本,它查看一个充满文件的目录,并将它们分类为纯文本或二进制文件。如果文件仅包含明文字符,则文件为纯文本,否则为二进制文件。到目前为止,我已经尝试了以下grep的排列:

#!/bin/bash
FILES=`ls`
for i in $FILES
do
    ########GREP SYNTAX###########
    if grep -qv -e[:cntrl:] $i
    ########/GREP SYNTAX##########
    then
        mv $i $i-plaintext.txt
    else
        mv $i $i-binary.txt
    fi
done

在grep语法行中,我也试过了没有-v标志并交换if语句的分支,以及它们与[:alnum:]和[:print:]的两种组合。这些变体中的所有六个产生一些标记为二进制的文件,其仅包含plantext和一些标记为明文的文件,其包含至少一个不可打印的字符。

我需要找到一种方法来识别包含可打印字符的文件,即A-Z,a-z,0-9,标点符号,空格和新行。包含任何不在此集合中的字符的所有文件都应归类为二进制文件。

我一直在靠墙试图将它分类半天。 救命! 提前致谢, 瑞克

2 个答案:

答案 0 :(得分:7)

首先你可以/应该做

for f in *

而不是将ls的输出放在变量中。这样做的主要原因是能够处理包含空格的文件名。

其次,您需要将字符类括在一组括号中,或者将这些字符视为文字。我会将它们用一组单引号括起来,以防止shell解释它们。不要使用-v并否定print类,看看它是否适合您。

if grep -aq -e '[^[:print:]]' "$f"

如该行所示,总是在变量包含文件名时引用它们。

mv "$f" "$f-plaintext.txt"

要让grep不要抱怨二进制文件,请使用-a

变量i通常用于整数或索引。使用ffile

最后:

#!/bin/bash
for f in *
do
    if grep -aq -e '[^[:print:]]' "$f"
    then
        mv "$f" "$f-binary.txt"
    else
        mv "$f" "$f-plaintext.txt"
    fi
done

答案 1 :(得分:0)

您可以使用grep的-I选项,它将二进制文件视为没有匹配的文件,只使用一个始终匹配的正则表达式(如空字符串):

if grep -qI -e '' $i