Выбрать главу

Пример 12-26. "Расширенная" команда strings

#!/bin/bash

# wstrings.sh: "word-strings" (расширенная команда "strings")

#

# Этот сценарий фильтрует вывод команды "strings" путем проверки на соответствие

#+ выводимых слов по файлу словаря.

# Таким способом эффективно "отсекается" весь "мусор",

#+ и выводятся только распознанные слова.

# =================================================================

# Стандартная проверка входных аргументов

ARGS=1

E_BADARGS=65

E_NOFILE=66

if [ $# -ne $ARGS ]

then

echo "Порядок использования: `basename $0` filename"

exit $E_BADARGS

fi

if [ ! -f "$1" ] # Проверка наличия файла.

then

echo "Файл \"$1\" не найден."

exit $E_NOFILE

fi

# =================================================================

MINSTRLEN=3 # Минимальная длина строки.

WORDFILE=/usr/share/dict/linux.words # Файл словаря.

# Можно указать иной

#+ файл словаря

#+ в формате -- "одно слово на строке".

wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \

tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '`

# Трансляция вывода от 'strings' с помощью нескольких 'tr'.

# "tr A-Z a-z" -- перевод в нижний регистр.

# "tr '[:space:]'" -- конвертирует пробелы в символы Z.

# "tr -cs '[:alpha:]' Z" -- конвертирует неалфавитные символы в символы Z,

#+ и удаляет повторяющиеся символы Z.

# "tr -s '\173-\377' Z" -- Конвертирует все символы, с кодами выше 'z' в Z

#+ и удаляет повторяющиеся символы Z,

#+ эта команда удалит все символы, которые не были распознаны предыдущими

#+ командами трансляции (tr).

# Наконец, "tr Z ' '" -- преобразует все символы Z в пробелы,

#+ которые будут рассматриваться в качестве разделителя слов в цикле, приведенном ниже.

# Обратите внимание на технику многоуровневой обработки с помощью 'tr',

#+ каждый раз эта команда вызывается с различным набором аргументов.

for word in $wlist # Важно:

# переменная $wlist не должна заключаться в кавычки.

# "$wlist" -- не сработает.

# Почему?

do

strlen=${#word} # Дина строки.

if [ "$strlen" -lt "$MINSTRLEN" ] # Не рассматривать короткие строки.

then

continue

fi

grep -Fw $word "$WORDFILE" # Проверка слова по словарю.

done

exit 0

Сравнение

diff, patch

diff: очень гибкая утилита сравнения файлов. Она выполняет построчное сравнение файлов. В отдельных случаях, таких как поиск по словарю, может оказаться полезной фильтрация файлов с помощью sort и uniq перед тем как отдать поток данных через конвейер утилите diff. diff file-1 file-2 -- выведет строки, имеющие отличия, указывая -- какому файлу, какая строка принадлежит.

С ключом --side-by-side, команда diff выведет сравниваемые файлы в две колонки, с указанием несовпадающих строк. Ключи -c и -u так же служат для облегчения интерпретации результатов работы diff.

Существует ряд интерфейсных оболочек для утилиты diff, среди них можно назвать: spiff, wdiff, xdiff и mgdiff.

Команда diff возвращает код завершения 0, если сравниваемые файлы идентичны и 1, если они отличаются. Это позволяет использовать diff в условных операторах внутри сценариев на языке командной оболочки (см. ниже).

В общем случае, diff используется для генерации файла различий, который используется как аргумент команды patch. Ключ -e отвечает за вывод файла различий в формате, пригодном для использования с ed или ex.

patch: гибкая утилита для "наложения заплат". С помощью файла различий, сгенерированного утилитой diff, утилита patch может использоваться для обновления устаревших версий файлов. Это позволяет распространять относительно небольшие "diff"-файлы вместо целых пакетов. Распространение "заплат" к ядру стало наиболее предпочтительным методом распространения более новых версий ядра Linux.