Найдите файлы, которые содержат ТОЛЬКО печатаемые символы в скрипте bash - PullRequest
1 голос
/ 21 сентября 2010

Я пытаюсь написать скрипт 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:]. Все шесть из этих вариантов создают некоторые файлы, помеченные как двоичные, которые состоят исключительно из текстового текста, и некоторые файлы, помеченные как открытый текст, которые содержат по крайней мере один непечатаемый символ.

Мне нужно найти способ определить файлы, которые только содержат печатаемые символы, то есть A-Z, a-z, 0-9, знаки пунктуации, пробелы и новые строки. Все файлы, содержащие любой символ, который не входит в этот набор, должны классифицироваться как двоичные.

Я бился головой о стену, пытаясь разобраться в этом на полдня. Помогите! Заранее спасибо, Rik

Ответы [ 2 ]

7 голосов
/ 21 сентября 2010

Сначала вы можете / должны сделать

for f in *

вместо помещения значения ls в переменную. Основная причина для этого заключается в том, чтобы иметь возможность обрабатывать имена файлов, которые включают пробелы.

Во-вторых, вам нужно заключить класс символов в набор скобок, или он будет рассматривать эти символы как литералы. И я бы заключил их в набор одинарных кавычек, чтобы защитить их от интерпретации оболочки. Не используйте -v и отрицайте класс print и посмотрите, подходит ли вам это.

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

И, как показано в этой строке, всегда заключайте в кавычки переменные, когда они содержат имена файлов.

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

Чтобы grep не жаловался на двоичные файлы, используйте -a.

Переменная i часто используется для целого числа или индекса. Используйте f или file.

Наконец:

#!/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
0 голосов
/ 21 сентября 2010

Вы можете использовать опцию -I grep, которая будет обрабатывать двоичные файлы как файлы без совпадения и просто использовать регулярное выражение, которое всегда будет совпадать (например, пустая строка):

if grep -qI -e '' $i
...